Makes gtest's tuple implementation work with Symbian 5th edition by bypassing 2 compiler bugs (by Zhanyong Wan); refactors for the event listener API (by Vlad Losev).

This commit is contained in:
zhanyong.wan 2009-06-24 23:02:50 +00:00
parent ef29ce3576
commit e6095deec8
6 changed files with 454 additions and 131 deletions

View File

@ -418,6 +418,9 @@ class TestResult {
// of successful test parts and the number of failed test parts.
int total_part_count() const;
// Returns the number of the test properties.
int test_property_count() const;
// Returns true iff the test passed (i.e. no test part failed).
bool Passed() const { return !Failed(); }
@ -436,6 +439,15 @@ class TestResult {
// Sets the elapsed time.
void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
// Returns the i-th test part result among all the results. i can range
// from 0 to test_property_count() - 1. If i is not in that range, returns
// NULL.
const TestPartResult* GetTestPartResult(int i) const;
// Returns the i-th test property. i can range from 0 to
// test_property_count() - 1. If i is not in that range, returns NULL.
const TestProperty* GetTestProperty(int i) const;
// Adds a test part result to the list.
void AddTestPartResult(const TestPartResult& test_part_result);
@ -639,6 +651,10 @@ class TestCase {
// Returns the elapsed time, in milliseconds.
internal::TimeInMillis elapsed_time() const { return elapsed_time_; }
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
const TestInfo* GetTestInfo(int i) const;
// Adds a TestInfo to this test case. Will delete the TestInfo upon
// destruction of the TestCase object.
void AddTestInfo(TestInfo * test_info);
@ -799,7 +815,50 @@ class UnitTest {
// Accessors for the implementation object.
internal::UnitTestImpl* impl() { return impl_; }
const internal::UnitTestImpl* impl() const { return impl_; }
private:
// Gets the number of successful test cases.
int successful_test_case_count() const;
// Gets the number of failed test cases.
int failed_test_case_count() const;
// Gets the number of all test cases.
int total_test_case_count() const;
// Gets the number of all test cases that contain at least one test
// that should run.
int test_case_to_run_count() const;
// Gets the number of successful tests.
int successful_test_count() const;
// Gets the number of failed tests.
int failed_test_count() const;
// Gets the number of disabled tests.
int disabled_test_count() const;
// Gets the number of all tests.
int total_test_count() const;
// Gets the number of tests that should run.
int test_to_run_count() const;
// Gets the elapsed time, in milliseconds.
internal::TimeInMillis elapsed_time() const;
// Returns true iff the unit test passed (i.e. all test cases passed).
bool Passed() const;
// Returns true iff the unit test failed (i.e. some test case failed
// or something outside of all tests failed).
bool Failed() const;
// Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL.
const internal::TestCase* GetTestCase(int i) const;
// ScopedTrace is a friend as it needs to modify the per-thread
// trace stack, which is a private member of UnitTest.
friend class internal::ScopedTrace;

View File

@ -38,18 +38,38 @@
#include <utility> // For ::std::pair.
// The compiler used in Symbian 5th Edition (__S60_50__) has a bug
// that prevents us from declaring the tuple template as a friend (it
// complains that tuple is redefined). This hack bypasses the bug by
// declaring the members that should otherwise be private as public.
#if defined(__SYMBIAN32__) && __S60_50__
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
private:
#endif
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
#define GTEST_0_TUPLE_(T) tuple<>
#define GTEST_1_TUPLE_(T) tuple<T##0>
#define GTEST_2_TUPLE_(T) tuple<T##0, T##1>
#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2>
#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3>
#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4>
#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5>
#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6>
#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, T##7>
#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
void, void, void>
#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
void, void, void>
#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
void, void, void>
#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
void, void, void>
#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
void, void, void>
#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
void, void, void>
#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
void, void, void>
#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
T##7, void, void>
#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
T##7, T##8>
T##7, T##8, void>
#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
T##7, T##8, T##9>
@ -162,7 +182,6 @@ template <GTEST_1_TYPENAMES_(T)>
class GTEST_1_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -180,7 +199,8 @@ class GTEST_1_TUPLE_(T) {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_1_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -194,7 +214,6 @@ template <GTEST_2_TYPENAMES_(T)>
class GTEST_2_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -221,7 +240,8 @@ class GTEST_2_TUPLE_(T) {
return *this;
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_2_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -237,7 +257,6 @@ template <GTEST_3_TYPENAMES_(T)>
class GTEST_3_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -256,7 +275,8 @@ class GTEST_3_TUPLE_(T) {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_3_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -274,7 +294,6 @@ template <GTEST_4_TYPENAMES_(T)>
class GTEST_4_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -295,7 +314,8 @@ class GTEST_4_TUPLE_(T) {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_4_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -315,7 +335,6 @@ template <GTEST_5_TYPENAMES_(T)>
class GTEST_5_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -337,7 +356,8 @@ class GTEST_5_TUPLE_(T) {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_5_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -359,7 +379,6 @@ template <GTEST_6_TYPENAMES_(T)>
class GTEST_6_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -382,7 +401,8 @@ class GTEST_6_TUPLE_(T) {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_6_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -406,7 +426,6 @@ template <GTEST_7_TYPENAMES_(T)>
class GTEST_7_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -429,7 +448,8 @@ class GTEST_7_TUPLE_(T) {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_7_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -455,7 +475,6 @@ template <GTEST_8_TYPENAMES_(T)>
class GTEST_8_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -479,7 +498,8 @@ class GTEST_8_TUPLE_(T) {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_8_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -507,7 +527,6 @@ template <GTEST_9_TYPENAMES_(T)>
class GTEST_9_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -531,7 +550,8 @@ class GTEST_9_TUPLE_(T) {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_9_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -561,7 +581,6 @@ template <GTEST_10_TYPENAMES_(T)>
class tuple {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -586,7 +605,8 @@ class tuple {
return CopyFrom(t);
}
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_10_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
f0_ = t.f0_;
@ -938,6 +958,7 @@ inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
#undef GTEST_9_TYPENAMES_
#undef GTEST_10_TYPENAMES_
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
#undef GTEST_BY_REF_
#undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_

View File

@ -39,15 +39,29 @@ $$ This meta comment fixes auto-indentation in Emacs. }}
#include <utility> // For ::std::pair.
// The compiler used in Symbian 5th Edition (__S60_50__) has a bug
// that prevents us from declaring the tuple template as a friend (it
// complains that tuple is redefined). This hack bypasses the bug by
// declaring the members that should otherwise be private as public.
#if defined(__SYMBIAN32__) && __S60_50__
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
private:
#endif
$range i 0..n-1
$range j 0..n
$range k 1..n
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
#define GTEST_0_TUPLE_(T) tuple<>
$for j [[
$range m 0..j-1
#define GTEST_$(j)_TUPLE_(T) tuple<$for m, [[T##$m]]>
$for k [[
$range m 0..k-1
$range m2 k..n-1
#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
]]
@ -125,7 +139,6 @@ template <GTEST_$(k)_TYPENAMES_(T)>
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple;
tuple() {}
@ -160,7 +173,8 @@ $if k == 2 [[
]]
private:
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
@ -313,6 +327,7 @@ $for j [[
]]
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
#undef GTEST_BY_REF_
#undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_

View File

@ -430,6 +430,26 @@ class List {
return NULL;
}
// Returns a pointer to the i-th element of the list, or NULL if i is not
// in range [0, size()).
const E* GetElement(int i) const {
if (i < 0 || i >= size())
return NULL;
const ListNode<E>* node = Head();
for (int index = 0; index < i && node != NULL; ++index, node = node->next())
continue;
return node ? &(node->element()) : NULL;
}
// Returns the i-th element of the list, or default_value if i is not
// in range [0, size()).
E GetElementOr(int i, E default_value) const {
const E* element = GetElement(i);
return element ? *element : default_value;
}
private:
ListNode<E>* head_; // The first node of the list.
ListNode<E>* last_; // The last node of the list.
@ -765,6 +785,12 @@ class UnitTestImpl {
return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
}
// Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL.
const TestCase* GetTestCase(int i) const {
return test_cases_.GetElementOr(i, NULL);
}
// Returns the TestResult for the test that's currently running, or
// the TestResult for the ad hoc test if no test is running.
internal::TestResult* current_test_result();

View File

@ -468,40 +468,80 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
class UnitTestEventListenerInterface {
public:
// The d'tor is pure virtual as this is an abstract class.
virtual ~UnitTestEventListenerInterface() = 0;
virtual ~UnitTestEventListenerInterface() {}
// Called before the unit test starts.
virtual void OnUnitTestStart(const UnitTest*) {}
virtual void OnUnitTestStart(const UnitTest& unit_test) = 0;
// Called after the unit test ends.
virtual void OnUnitTestEnd(const UnitTest*) {}
virtual void OnUnitTestEnd(const UnitTest& unit_test) = 0;
// Called before the test case starts.
virtual void OnTestCaseStart(const TestCase*) {}
virtual void OnTestCaseStart(const TestCase& test_case) = 0;
// Called after the test case ends.
virtual void OnTestCaseEnd(const TestCase*) {}
virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
// Called before the global set-up starts.
virtual void OnGlobalSetUpStart(const UnitTest*) {}
virtual void OnGlobalSetUpStart(const UnitTest& unit_test) = 0;
// Called after the global set-up ends.
virtual void OnGlobalSetUpEnd(const UnitTest*) {}
virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) = 0;
// Called before the global tear-down starts.
virtual void OnGlobalTearDownStart(const UnitTest*) {}
virtual void OnGlobalTearDownStart(const UnitTest& unit_test) = 0;
// Called after the global tear-down ends.
virtual void OnGlobalTearDownEnd(const UnitTest*) {}
virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) = 0;
// Called before the test starts.
virtual void OnTestStart(const TestInfo*) {}
virtual void OnTestStart(const TestInfo& test_info) = 0;
// Called after the test ends.
virtual void OnTestEnd(const TestInfo*) {}
virtual void OnTestEnd(const TestInfo& test_info) = 0;
// Called after an assertion.
virtual void OnNewTestPartResult(const TestPartResult*) {}
virtual void OnNewTestPartResult(const TestPartResult& test_part_result) = 0;
};
// The convenience class for users who need to override just one or two
// methods and are not concerned that a possible change to a signature of
// the methods they override will not be caught during the build.
class EmptyTestEventListener : public UnitTestEventListenerInterface {
public:
// Called before the unit test starts.
virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) {}
// Called after the unit test ends.
virtual void OnUnitTestEnd(const UnitTest& /*unit_test*/) {}
// Called before the test case starts.
virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
// Called after the test case ends.
virtual void OnTestCaseEnd(const TestCase& /*test_case&*/) {}
// Called before the global set-up starts.
virtual void OnGlobalSetUpStart(const UnitTest& /*unit_test*/) {}
// Called after the global set-up ends.
virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {}
// Called before the global tear-down starts.
virtual void OnGlobalTearDownStart(const UnitTest& /*unit_test*/) {}
// Called after the global tear-down ends.
virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
// Called before the test starts.
virtual void OnTestStart(const TestInfo& /*test_info*/) {}
// Called after the test ends.
virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
// Called after an assertion.
virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) {
}
};
// The c'tor sets this object as the test part result reporter used by
@ -638,7 +678,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
const TestPartResult& result) {
unit_test_->current_test_result()->AddTestPartResult(result);
unit_test_->result_printer()->OnNewTestPartResult(&result);
unit_test_->result_printer()->OnNewTestPartResult(result);
}
DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
@ -1790,6 +1830,19 @@ TestResult::TestResult()
TestResult::~TestResult() {
}
// Returns the i-th test part result among all the results. i can range
// from 0 to total_part_count() - 1. If i is not in that range, returns
// NULL.
const TestPartResult* TestResult::GetTestPartResult(int i) const {
return test_part_results_->GetElement(i);
}
// Returns the i-th test property. i can range from 0 to
// test_property_count() - 1. If i is not in that range, returns NULL.
const TestProperty* TestResult::GetTestProperty(int i) const {
return test_properties_->GetElement(i);
}
// Clears the test part results.
void TestResult::ClearTestPartResults() {
test_part_results_->Clear();
@ -1887,6 +1940,11 @@ int TestResult::total_part_count() const {
return test_part_results_->size();
}
// Returns the number of the test properties.
int TestResult::test_property_count() const {
return test_properties_->size();
}
} // namespace internal
// class Test
@ -2261,7 +2319,7 @@ void TestInfoImpl::Run() {
// start.
UnitTestEventListenerInterface* const result_printer =
impl->result_printer();
result_printer->OnTestStart(parent_);
result_printer->OnTestStart(*parent_);
const TimeInMillis start = GetTimeInMillis();
@ -2304,7 +2362,7 @@ void TestInfoImpl::Run() {
result_.set_elapsed_time(GetTimeInMillis() - start);
// Notifies the unit test event listener that a test has just finished.
result_printer->OnTestEnd(parent_);
result_printer->OnTestEnd(*parent_);
// Tells UnitTest to stop associating assertion results to this
// test.
@ -2366,6 +2424,12 @@ TestCase::~TestCase() {
test_info_list_ = NULL;
}
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
const TestInfo* TestCase::GetTestInfo(int i) const {
return test_info_list_->GetElementOr(i, NULL);
}
// Adds a test to this test case. Will delete the test upon
// destruction of the TestCase object.
void TestCase::AddTestInfo(TestInfo * test_info) {
@ -2382,7 +2446,7 @@ void TestCase::Run() {
UnitTestEventListenerInterface * const result_printer =
impl->result_printer();
result_printer->OnTestCaseStart(this);
result_printer->OnTestCaseStart(*this);
impl->os_stack_trace_getter()->UponLeavingGTest();
set_up_tc_();
@ -2392,7 +2456,7 @@ void TestCase::Run() {
impl->os_stack_trace_getter()->UponLeavingGTest();
tear_down_tc_();
result_printer->OnTestCaseEnd(this);
result_printer->OnTestCaseEnd(*this);
impl->set_current_test_case(NULL);
}
@ -2425,15 +2489,9 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
} // namespace internal
// class UnitTestEventListenerInterface
// The virtual d'tor.
UnitTestEventListenerInterface::~UnitTestEventListenerInterface() {
}
// A result printer that never prints anything. Used in the child process
// of an exec-style death test to avoid needless output clutter.
class NullUnitTestResultPrinter : public UnitTestEventListenerInterface {};
class NullUnitTestResultPrinter : public EmptyTestEventListener {};
// Formats a countable noun. Depending on its quantity, either the
// singular form or the plural form is used. e.g.
@ -2628,24 +2686,25 @@ class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface {
// The following methods override what's in the
// UnitTestEventListenerInterface class.
virtual void OnUnitTestStart(const UnitTest * unit_test);
virtual void OnGlobalSetUpStart(const UnitTest*);
virtual void OnTestCaseStart(const TestCase * test_case);
virtual void OnTestCaseEnd(const TestCase * test_case);
virtual void OnTestStart(const TestInfo * test_info);
virtual void OnNewTestPartResult(const TestPartResult * result);
virtual void OnTestEnd(const TestInfo * test_info);
virtual void OnGlobalTearDownStart(const UnitTest*);
virtual void OnUnitTestEnd(const UnitTest * unit_test);
virtual void OnUnitTestStart(const UnitTest& unit_test);
virtual void OnGlobalSetUpStart(const UnitTest& unit_test);
virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {}
virtual void OnTestCaseStart(const TestCase& test_case);
virtual void OnTestCaseEnd(const TestCase& test_case);
virtual void OnTestStart(const TestInfo& test_info);
virtual void OnNewTestPartResult(const TestPartResult& result);
virtual void OnTestEnd(const TestInfo& test_info);
virtual void OnGlobalTearDownStart(const UnitTest& unit_test);
virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
virtual void OnUnitTestEnd(const UnitTest& unit_test);
private:
internal::String test_case_name_;
};
// Called before the unit test starts.
void PrettyUnitTestResultPrinter::OnUnitTestStart(
const UnitTest * unit_test) {
const char * const filter = GTEST_FLAG(filter).c_str();
void PrettyUnitTestResultPrinter::OnUnitTestStart(const UnitTest& unit_test) {
const char* const filter = GTEST_FLAG(filter).c_str();
// Prints the filter if it's not *. This reminds the user that some
// tests may be skipped.
@ -2661,7 +2720,7 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart(
internal::posix::GetEnv(kTestTotalShards));
}
const internal::UnitTestImpl* const impl = unit_test->impl();
const internal::UnitTestImpl* const impl = unit_test.impl();
ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("Running %s from %s.\n",
FormatTestCount(impl->test_to_run_count()).c_str(),
@ -2669,62 +2728,61 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart(
fflush(stdout);
}
void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(const UnitTest*) {
void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(
const UnitTest& /*unit_test*/) {
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("Global test environment set-up.\n");
fflush(stdout);
}
void PrettyUnitTestResultPrinter::OnTestCaseStart(
const TestCase * test_case) {
test_case_name_ = test_case->name();
void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
test_case_name_ = test_case.name();
const internal::String counts =
FormatCountableNoun(test_case->test_to_run_count(), "test", "tests");
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s", counts.c_str(), test_case_name_.c_str());
if (test_case->comment()[0] == '\0') {
if (test_case.comment()[0] == '\0') {
printf("\n");
} else {
printf(", where %s\n", test_case->comment());
printf(", where %s\n", test_case.comment());
}
fflush(stdout);
}
void PrettyUnitTestResultPrinter::OnTestCaseEnd(
const TestCase * test_case) {
void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
if (!GTEST_FLAG(print_time)) return;
test_case_name_ = test_case->name();
test_case_name_ = test_case.name();
const internal::String counts =
FormatCountableNoun(test_case->test_to_run_count(), "test", "tests");
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s (%s ms total)\n\n",
counts.c_str(), test_case_name_.c_str(),
internal::StreamableToString(test_case->elapsed_time()).c_str());
internal::StreamableToString(test_case.elapsed_time()).c_str());
fflush(stdout);
}
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo * test_info) {
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
PrintTestName(test_case_name_.c_str(), test_info->name());
if (test_info->comment()[0] == '\0') {
PrintTestName(test_case_name_.c_str(), test_info.name());
if (test_info.comment()[0] == '\0') {
printf("\n");
} else {
printf(", where %s\n", test_info->comment());
printf(", where %s\n", test_info.comment());
}
fflush(stdout);
}
void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) {
if (test_info->result()->Passed()) {
void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
if (test_info.result()->Passed()) {
ColoredPrintf(COLOR_GREEN, "[ OK ] ");
} else {
ColoredPrintf(COLOR_RED, "[ FAILED ] ");
}
PrintTestName(test_case_name_.c_str(), test_info->name());
PrintTestName(test_case_name_.c_str(), test_info.name());
if (GTEST_FLAG(print_time)) {
printf(" (%s ms)\n", internal::StreamableToString(
test_info->result()->elapsed_time()).c_str());
test_info.result()->elapsed_time()).c_str());
} else {
printf("\n");
}
@ -2733,17 +2791,18 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) {
// Called after an assertion failure.
void PrettyUnitTestResultPrinter::OnNewTestPartResult(
const TestPartResult * result) {
const TestPartResult& result) {
// If the test part succeeded, we don't need to do anything.
if (result->type() == TPRT_SUCCESS)
if (result.type() == TPRT_SUCCESS)
return;
// Print failure message from the assertion (e.g. expected this and got that).
PrintTestPartResult(*result);
PrintTestPartResult(result);
fflush(stdout);
}
void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(const UnitTest*) {
void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(
const UnitTest& /*unit_test*/) {
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("Global test environment tear-down\n");
fflush(stdout);
@ -2788,9 +2847,8 @@ static void PrintFailedTestsPretty(const UnitTestImpl* impl) {
} // namespace internal
void PrettyUnitTestResultPrinter::OnUnitTestEnd(
const UnitTest * unit_test) {
const internal::UnitTestImpl* const impl = unit_test->impl();
void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
const internal::UnitTestImpl* const impl = unit_test.impl();
ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("%s from %s ran.",
@ -2841,17 +2899,17 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
virtual ~UnitTestEventsRepeater();
void AddListener(UnitTestEventListenerInterface *listener);
virtual void OnUnitTestStart(const UnitTest* unit_test);
virtual void OnUnitTestEnd(const UnitTest* unit_test);
virtual void OnGlobalSetUpStart(const UnitTest* unit_test);
virtual void OnGlobalSetUpEnd(const UnitTest* unit_test);
virtual void OnGlobalTearDownStart(const UnitTest* unit_test);
virtual void OnGlobalTearDownEnd(const UnitTest* unit_test);
virtual void OnTestCaseStart(const TestCase* test_case);
virtual void OnTestCaseEnd(const TestCase* test_case);
virtual void OnTestStart(const TestInfo* test_info);
virtual void OnTestEnd(const TestInfo* test_info);
virtual void OnNewTestPartResult(const TestPartResult* result);
virtual void OnUnitTestStart(const UnitTest& unit_test);
virtual void OnUnitTestEnd(const UnitTest& unit_test);
virtual void OnGlobalSetUpStart(const UnitTest& unit_test);
virtual void OnGlobalSetUpEnd(const UnitTest& unit_test);
virtual void OnGlobalTearDownStart(const UnitTest& unit_test);
virtual void OnGlobalTearDownEnd(const UnitTest& unit_test);
virtual void OnTestCaseStart(const TestCase& test_case);
virtual void OnTestCaseEnd(const TestCase& test_case);
virtual void OnTestStart(const TestInfo& test_info);
virtual void OnTestEnd(const TestInfo& test_info);
virtual void OnNewTestPartResult(const TestPartResult& result);
private:
Listeners listeners_;
@ -2875,7 +2933,7 @@ void UnitTestEventsRepeater::AddListener(
// Since the methods are identical, use a macro to reduce boilerplate.
// This defines a member that repeats the call to all listeners.
#define GTEST_REPEATER_METHOD_(Name, Type) \
void UnitTestEventsRepeater::Name(const Type* parameter) { \
void UnitTestEventsRepeater::Name(const Type& parameter) { \
for (ListenersNode* listener = listeners_.Head(); \
listener != NULL; \
listener = listener->next()) { \
@ -2900,11 +2958,11 @@ GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult)
// End PrettyUnitTestResultPrinter
// This class generates an XML output file.
class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface {
class XmlUnitTestResultPrinter : public EmptyTestEventListener {
public:
explicit XmlUnitTestResultPrinter(const char* output_file);
virtual void OnUnitTestEnd(const UnitTest* unit_test);
virtual void OnUnitTestEnd(const UnitTest& unit_test);
private:
// Is c a whitespace character that is normalized to a space character
@ -2944,7 +3002,7 @@ class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface {
static void PrintXmlTestCase(FILE* out, const TestCase* test_case);
// Prints an XML summary of unit_test to output stream out.
static void PrintXmlUnitTest(FILE* out, const UnitTest* unit_test);
static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test);
// Produces a string representing the test properties in a result as space
// delimited XML attributes based on the property key="value" pairs.
@ -2970,7 +3028,7 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
}
// Called after the unit test ends.
void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) {
void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
FILE* xmlout = NULL;
internal::FilePath output_file(output_file_);
internal::FilePath output_dir(output_file.RemoveFileName());
@ -3149,8 +3207,8 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
// Prints an XML summary of unit_test to output stream out.
void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
const UnitTest* unit_test) {
const internal::UnitTestImpl* const impl = unit_test->impl();
const UnitTest& unit_test) {
const internal::UnitTestImpl* const impl = unit_test.impl();
fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
fprintf(out,
"<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
@ -3267,6 +3325,64 @@ UnitTest * UnitTest::GetInstance() {
#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
}
// Gets the number of successful test cases.
int UnitTest::successful_test_case_count() const {
return impl()->successful_test_case_count();
}
// Gets the number of failed test cases.
int UnitTest::failed_test_case_count() const {
return impl()->failed_test_case_count();
}
// Gets the number of all test cases.
int UnitTest::total_test_case_count() const {
return impl()->total_test_case_count();
}
// Gets the number of all test cases that contain at least one test
// that should run.
int UnitTest::test_case_to_run_count() const {
return impl()->test_case_to_run_count();
}
// Gets the number of successful tests.
int UnitTest::successful_test_count() const {
return impl()->successful_test_count();
}
// Gets the number of failed tests.
int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
// Gets the number of disabled tests.
int UnitTest::disabled_test_count() const {
return impl()->disabled_test_count();
}
// Gets the number of all tests.
int UnitTest::total_test_count() const { return impl()->total_test_count(); }
// Gets the number of tests that should run.
int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
// Gets the elapsed time, in milliseconds.
internal::TimeInMillis UnitTest::elapsed_time() const {
return impl()->elapsed_time();
}
// Returns true iff the unit test passed (i.e. all test cases passed).
bool UnitTest::Passed() const { return impl()->Passed(); }
// Returns true iff the unit test failed (i.e. some test case failed
// or something outside of all tests failed).
bool UnitTest::Failed() const { return impl()->Failed(); }
// Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL.
const TestCase* UnitTest::GetTestCase(int i) const {
return impl()->GetTestCase(i);
}
// Registers and returns a global test environment. When a test
// program is run, all global test environments will be set-up in the
// order they were registered. After all tests in the program have
@ -3683,16 +3799,16 @@ int UnitTestImpl::RunAllTests() {
// Tells the unit test event listener that the tests are about to
// start.
printer->OnUnitTestStart(parent_);
printer->OnUnitTestStart(*parent_);
const TimeInMillis start = GetTimeInMillis();
// Runs each test case if there is at least one test to run.
if (has_tests_to_run) {
// Sets up all environments beforehand.
printer->OnGlobalSetUpStart(parent_);
printer->OnGlobalSetUpStart(*parent_);
environments_.ForEach(SetUpEnvironment);
printer->OnGlobalSetUpEnd(parent_);
printer->OnGlobalSetUpEnd(*parent_);
// Runs the tests only if there was no fatal failure during global
// set-up.
@ -3701,16 +3817,16 @@ int UnitTestImpl::RunAllTests() {
}
// Tears down all environments in reverse order afterwards.
printer->OnGlobalTearDownStart(parent_);
printer->OnGlobalTearDownStart(*parent_);
environments_in_reverse_order_.ForEach(TearDownEnvironment);
printer->OnGlobalTearDownEnd(parent_);
printer->OnGlobalTearDownEnd(*parent_);
}
elapsed_time_ = GetTimeInMillis() - start;
// Tells the unit test event listener that the tests have just
// finished.
printer->OnUnitTestEnd(parent_);
printer->OnUnitTestEnd(*parent_);
// Gets the result and clears it.
if (!Passed()) {

View File

@ -148,7 +148,6 @@ using testing::internal::String;
using testing::internal::TestProperty;
using testing::internal::TestResult;
using testing::internal::ThreadLocal;
using testing::internal::UnitTestImpl;
using testing::internal::WideStringToUtf8;
// This line tests that we can define tests in an unnamed namespace.
@ -526,6 +525,19 @@ TEST(ListTest, InsertAfterNotAtBeginning) {
EXPECT_EQ(3, a.Last()->element());
}
// Tests the GetElement accessor.
TEST(ListTest, GetElement) {
List<int> a;
a.PushBack(0);
a.PushBack(1);
a.PushBack(2);
EXPECT_EQ(&(a.Head()->element()), a.GetElement(0));
EXPECT_EQ(&(a.Head()->next()->element()), a.GetElement(1));
EXPECT_EQ(&(a.Head()->next()->next()->element()), a.GetElement(2));
EXPECT_TRUE(a.GetElement(3) == NULL);
EXPECT_TRUE(a.GetElement(-1) == NULL);
}
// Tests the String class.
@ -1085,23 +1097,38 @@ class TestResultTest : public Test {
delete r1;
delete r2;
}
// Helper that compares two two TestPartResults.
static void CompareTestPartResult(const TestPartResult* expected,
const TestPartResult* actual) {
ASSERT_TRUE(actual != NULL);
EXPECT_EQ(expected->type(), actual->type());
EXPECT_STREQ(expected->file_name(), actual->file_name());
EXPECT_EQ(expected->line_number(), actual->line_number());
EXPECT_STREQ(expected->summary(), actual->summary());
EXPECT_STREQ(expected->message(), actual->message());
EXPECT_EQ(expected->passed(), actual->passed());
EXPECT_EQ(expected->failed(), actual->failed());
EXPECT_EQ(expected->nonfatally_failed(), actual->nonfatally_failed());
EXPECT_EQ(expected->fatally_failed(), actual->fatally_failed());
}
};
// Tests TestResult::test_part_results()
// Tests TestResult::test_part_results().
TEST_F(TestResultTest, test_part_results) {
ASSERT_EQ(0u, r0->test_part_results().size());
ASSERT_EQ(1u, r1->test_part_results().size());
ASSERT_EQ(2u, r2->test_part_results().size());
}
// Tests TestResult::successful_part_count()
// Tests TestResult::successful_part_count().
TEST_F(TestResultTest, successful_part_count) {
ASSERT_EQ(0u, r0->successful_part_count());
ASSERT_EQ(1u, r1->successful_part_count());
ASSERT_EQ(1u, r2->successful_part_count());
}
// Tests TestResult::failed_part_count()
// Tests TestResult::failed_part_count().
TEST_F(TestResultTest, failed_part_count) {
ASSERT_EQ(0u, r0->failed_part_count());
ASSERT_EQ(0u, r1->failed_part_count());
@ -1115,27 +1142,35 @@ TEST_F(TestResultTest, GetFailedPartCount) {
ASSERT_EQ(1u, GetFailedPartCount(r2));
}
// Tests TestResult::total_part_count()
// Tests TestResult::total_part_count().
TEST_F(TestResultTest, total_part_count) {
ASSERT_EQ(0u, r0->total_part_count());
ASSERT_EQ(1u, r1->total_part_count());
ASSERT_EQ(2u, r2->total_part_count());
}
// Tests TestResult::Passed()
// Tests TestResult::Passed().
TEST_F(TestResultTest, Passed) {
ASSERT_TRUE(r0->Passed());
ASSERT_TRUE(r1->Passed());
ASSERT_FALSE(r2->Passed());
}
// Tests TestResult::Failed()
// Tests TestResult::Failed().
TEST_F(TestResultTest, Failed) {
ASSERT_FALSE(r0->Failed());
ASSERT_FALSE(r1->Failed());
ASSERT_TRUE(r2->Failed());
}
// Tests TestResult::GetTestPartResult().
TEST_F(TestResultTest, GetTestPartResult) {
CompareTestPartResult(pr1, r2->GetTestPartResult(0));
CompareTestPartResult(pr2, r2->GetTestPartResult(1));
EXPECT_TRUE(r2->GetTestPartResult(2) == NULL);
EXPECT_TRUE(r2->GetTestPartResult(-1) == NULL);
}
// Tests TestResult::test_properties() has no properties when none are added.
TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) {
TestResult test_result;
@ -1195,6 +1230,49 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) {
EXPECT_STREQ("22", actual_property_2.value());
}
// Tests TestResult::test_property_count().
TEST(TestResultPropertyTest, TestPropertyCount) {
TestResult test_result;
TestProperty property_1("key_1", "1");
TestProperty property_2("key_2", "2");
ASSERT_EQ(0, test_result.test_property_count());
test_result.RecordProperty(property_1);
ASSERT_EQ(1, test_result.test_property_count());
test_result.RecordProperty(property_2);
ASSERT_EQ(2, test_result.test_property_count());
}
// Tests TestResult::GetTestProperty().
TEST(TestResultPropertyTest, GetTestProperty) {
TestResult test_result;
TestProperty property_1("key_1", "1");
TestProperty property_2("key_2", "2");
TestProperty property_3("key_3", "3");
test_result.RecordProperty(property_1);
test_result.RecordProperty(property_2);
test_result.RecordProperty(property_3);
const TestProperty* fetched_property_1 = test_result.GetTestProperty(0);
const TestProperty* fetched_property_2 = test_result.GetTestProperty(1);
const TestProperty* fetched_property_3 = test_result.GetTestProperty(2);
ASSERT_TRUE(fetched_property_1 != NULL);
EXPECT_STREQ("key_1", fetched_property_1->key());
EXPECT_STREQ("1", fetched_property_1->value());
ASSERT_TRUE(fetched_property_2 != NULL);
EXPECT_STREQ("key_2", fetched_property_2->key());
EXPECT_STREQ("2", fetched_property_2->value());
ASSERT_TRUE(fetched_property_3 != NULL);
EXPECT_STREQ("key_3", fetched_property_3->key());
EXPECT_STREQ("3", fetched_property_3->value());
ASSERT_TRUE(test_result.GetTestProperty(3) == NULL);
ASSERT_TRUE(test_result.GetTestProperty(-1) == NULL);
}
// When a property using a reserved key is supplied to this function, it tests
// that a non-fatal failure is added, a fatal failure is not added, and that the
// property is not recorded.
@ -3061,6 +3139,10 @@ TEST(AssertionTest, ASSERT_EQ) {
TEST(AssertionTest, ASSERT_EQ_NULL) {
// A success.
const char* p = NULL;
// Some older GCC versions may issue a spurious waring in this or the next
// assertion statement. This warning should not be suppressed with
// static_cast since the test verifies the ability to use bare NULL as the
// expected parameter to the macro.
ASSERT_EQ(NULL, p);
// A failure.
@ -3614,6 +3696,10 @@ TEST(ExpectTest, EXPECT_EQ_Double) {
TEST(ExpectTest, EXPECT_EQ_NULL) {
// A success.
const char* p = NULL;
// Some older GCC versions may issue a spurious waring in this or the next
// assertion statement. This warning should not be suppressed with
// static_cast since the test verifies the ability to use bare NULL as the
// expected parameter to the macro.
EXPECT_EQ(NULL, p);
// A failure.
@ -5207,7 +5293,7 @@ class CurrentTestInfoTest : public Test {
// There should be no tests running at this point.
const TestInfo* test_info =
UnitTest::GetInstance()->current_test_info();
EXPECT_EQ(NULL, test_info)
EXPECT_TRUE(test_info == NULL)
<< "There should be no tests running at this point.";
}
@ -5216,7 +5302,7 @@ class CurrentTestInfoTest : public Test {
static void TearDownTestCase() {
const TestInfo* test_info =
UnitTest::GetInstance()->current_test_info();
EXPECT_EQ(NULL, test_info)
EXPECT_TRUE(test_info == NULL)
<< "There should be no tests running at this point.";
}
};