Commit e6095dee authored by zhanyong.wan's avatar zhanyong.wan
Browse files

Makes gtest's tuple implementation work with Symbian 5th edition by bypassing...

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).
parent ef29ce35
...@@ -418,6 +418,9 @@ class TestResult { ...@@ -418,6 +418,9 @@ class TestResult {
// of successful test parts and the number of failed test parts. // of successful test parts and the number of failed test parts.
int total_part_count() const; 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). // Returns true iff the test passed (i.e. no test part failed).
bool Passed() const { return !Failed(); } bool Passed() const { return !Failed(); }
...@@ -436,6 +439,15 @@ class TestResult { ...@@ -436,6 +439,15 @@ class TestResult {
// Sets the elapsed time. // Sets the elapsed time.
void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } 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. // Adds a test part result to the list.
void AddTestPartResult(const TestPartResult& test_part_result); void AddTestPartResult(const TestPartResult& test_part_result);
...@@ -639,6 +651,10 @@ class TestCase { ...@@ -639,6 +651,10 @@ class TestCase {
// Returns the elapsed time, in milliseconds. // Returns the elapsed time, in milliseconds.
internal::TimeInMillis elapsed_time() const { return elapsed_time_; } 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 // Adds a TestInfo to this test case. Will delete the TestInfo upon
// destruction of the TestCase object. // destruction of the TestCase object.
void AddTestInfo(TestInfo * test_info); void AddTestInfo(TestInfo * test_info);
...@@ -799,7 +815,50 @@ class UnitTest { ...@@ -799,7 +815,50 @@ class UnitTest {
// Accessors for the implementation object. // Accessors for the implementation object.
internal::UnitTestImpl* impl() { return impl_; } internal::UnitTestImpl* impl() { return impl_; }
const internal::UnitTestImpl* impl() const { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; }
private: 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 // ScopedTrace is a friend as it needs to modify the per-thread
// trace stack, which is a private member of UnitTest. // trace stack, which is a private member of UnitTest.
friend class internal::ScopedTrace; friend class internal::ScopedTrace;
......
...@@ -38,18 +38,38 @@ ...@@ -38,18 +38,38 @@
#include <utility> // For ::std::pair. #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. // GTEST_n_TUPLE_(T) is the type of an n-tuple.
#define GTEST_0_TUPLE_(T) tuple<> #define GTEST_0_TUPLE_(T) tuple<>
#define GTEST_1_TUPLE_(T) tuple<T##0> #define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
#define GTEST_2_TUPLE_(T) tuple<T##0, T##1> void, void, void>
#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2> #define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3> void, void, void>
#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4> #define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, 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>
#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6> #define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, 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, 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, \ #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, \ #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> T##7, T##8, T##9>
...@@ -162,7 +182,6 @@ template <GTEST_1_TYPENAMES_(T)> ...@@ -162,7 +182,6 @@ template <GTEST_1_TYPENAMES_(T)>
class GTEST_1_TUPLE_(T) { class GTEST_1_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -180,7 +199,8 @@ class GTEST_1_TUPLE_(T) { ...@@ -180,7 +199,8 @@ class GTEST_1_TUPLE_(T) {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_1_TYPENAMES_(U)> template <GTEST_1_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -194,7 +214,6 @@ template <GTEST_2_TYPENAMES_(T)> ...@@ -194,7 +214,6 @@ template <GTEST_2_TYPENAMES_(T)>
class GTEST_2_TUPLE_(T) { class GTEST_2_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -221,7 +240,8 @@ class GTEST_2_TUPLE_(T) { ...@@ -221,7 +240,8 @@ class GTEST_2_TUPLE_(T) {
return *this; return *this;
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_2_TYPENAMES_(U)> template <GTEST_2_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -237,7 +257,6 @@ template <GTEST_3_TYPENAMES_(T)> ...@@ -237,7 +257,6 @@ template <GTEST_3_TYPENAMES_(T)>
class GTEST_3_TUPLE_(T) { class GTEST_3_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -256,7 +275,8 @@ class GTEST_3_TUPLE_(T) { ...@@ -256,7 +275,8 @@ class GTEST_3_TUPLE_(T) {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_3_TYPENAMES_(U)> template <GTEST_3_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -274,7 +294,6 @@ template <GTEST_4_TYPENAMES_(T)> ...@@ -274,7 +294,6 @@ template <GTEST_4_TYPENAMES_(T)>
class GTEST_4_TUPLE_(T) { class GTEST_4_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -295,7 +314,8 @@ class GTEST_4_TUPLE_(T) { ...@@ -295,7 +314,8 @@ class GTEST_4_TUPLE_(T) {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_4_TYPENAMES_(U)> template <GTEST_4_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -315,7 +335,6 @@ template <GTEST_5_TYPENAMES_(T)> ...@@ -315,7 +335,6 @@ template <GTEST_5_TYPENAMES_(T)>
class GTEST_5_TUPLE_(T) { class GTEST_5_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -337,7 +356,8 @@ class GTEST_5_TUPLE_(T) { ...@@ -337,7 +356,8 @@ class GTEST_5_TUPLE_(T) {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_5_TYPENAMES_(U)> template <GTEST_5_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -359,7 +379,6 @@ template <GTEST_6_TYPENAMES_(T)> ...@@ -359,7 +379,6 @@ template <GTEST_6_TYPENAMES_(T)>
class GTEST_6_TUPLE_(T) { class GTEST_6_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -382,7 +401,8 @@ class GTEST_6_TUPLE_(T) { ...@@ -382,7 +401,8 @@ class GTEST_6_TUPLE_(T) {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_6_TYPENAMES_(U)> template <GTEST_6_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -406,7 +426,6 @@ template <GTEST_7_TYPENAMES_(T)> ...@@ -406,7 +426,6 @@ template <GTEST_7_TYPENAMES_(T)>
class GTEST_7_TUPLE_(T) { class GTEST_7_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -429,7 +448,8 @@ class GTEST_7_TUPLE_(T) { ...@@ -429,7 +448,8 @@ class GTEST_7_TUPLE_(T) {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_7_TYPENAMES_(U)> template <GTEST_7_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -455,7 +475,6 @@ template <GTEST_8_TYPENAMES_(T)> ...@@ -455,7 +475,6 @@ template <GTEST_8_TYPENAMES_(T)>
class GTEST_8_TUPLE_(T) { class GTEST_8_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -479,7 +498,8 @@ class GTEST_8_TUPLE_(T) { ...@@ -479,7 +498,8 @@ class GTEST_8_TUPLE_(T) {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_8_TYPENAMES_(U)> template <GTEST_8_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -507,7 +527,6 @@ template <GTEST_9_TYPENAMES_(T)> ...@@ -507,7 +527,6 @@ template <GTEST_9_TYPENAMES_(T)>
class GTEST_9_TUPLE_(T) { class GTEST_9_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -531,7 +550,8 @@ class GTEST_9_TUPLE_(T) { ...@@ -531,7 +550,8 @@ class GTEST_9_TUPLE_(T) {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_9_TYPENAMES_(U)> template <GTEST_9_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -561,7 +581,6 @@ template <GTEST_10_TYPENAMES_(T)> ...@@ -561,7 +581,6 @@ template <GTEST_10_TYPENAMES_(T)>
class tuple { class tuple {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -586,7 +605,8 @@ class tuple { ...@@ -586,7 +605,8 @@ class tuple {
return CopyFrom(t); return CopyFrom(t);
} }
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_10_TYPENAMES_(U)> template <GTEST_10_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
f0_ = t.f0_; f0_ = t.f0_;
...@@ -938,6 +958,7 @@ inline bool operator!=(const GTEST_10_TUPLE_(T)& t, ...@@ -938,6 +958,7 @@ inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
#undef GTEST_9_TYPENAMES_ #undef GTEST_9_TYPENAMES_
#undef GTEST_10_TYPENAMES_ #undef GTEST_10_TYPENAMES_
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
#undef GTEST_BY_REF_ #undef GTEST_BY_REF_
#undef GTEST_ADD_REF_ #undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_ #undef GTEST_TUPLE_ELEMENT_
......
...@@ -39,15 +39,29 @@ $$ This meta comment fixes auto-indentation in Emacs. }} ...@@ -39,15 +39,29 @@ $$ This meta comment fixes auto-indentation in Emacs. }}
#include <utility> // For ::std::pair. #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 i 0..n-1
$range j 0..n $range j 0..n
$range k 1..n $range k 1..n
// GTEST_n_TUPLE_(T) is the type of an n-tuple. // GTEST_n_TUPLE_(T) is the type of an n-tuple.
#define GTEST_0_TUPLE_(T) tuple<>
$for j [[ $for k [[
$range m 0..j-1 $range m 0..k-1
#define GTEST_$(j)_TUPLE_(T) tuple<$for m, [[T##$m]]> $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)> ...@@ -125,7 +139,6 @@ template <GTEST_$(k)_TYPENAMES_(T)>
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple;
tuple() {} tuple() {}
...@@ -160,7 +173,8 @@ $if k == 2 [[ ...@@ -160,7 +173,8 @@ $if k == 2 [[
]] ]]
private: GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_$(k)_TYPENAMES_(U)> template <GTEST_$(k)_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
...@@ -313,6 +327,7 @@ $for j [[ ...@@ -313,6 +327,7 @@ $for j [[
]] ]]
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
#undef GTEST_BY_REF_ #undef GTEST_BY_REF_
#undef GTEST_ADD_REF_ #undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_ #undef GTEST_TUPLE_ELEMENT_
......
...@@ -430,6 +430,26 @@ class List { ...@@ -430,6 +430,26 @@ class List {
return NULL; 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: private:
ListNode<E>* head_; // The first node of the list. ListNode<E>* head_; // The first node of the list.
ListNode<E>* last_; // The last node of the list. ListNode<E>* last_; // The last node of the list.
...@@ -765,6 +785,12 @@ class UnitTestImpl { ...@@ -765,6 +785,12 @@ class UnitTestImpl {
return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); 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 // Returns the TestResult for the test that's currently running, or
// the TestResult for the ad hoc test if no test is running. // the TestResult for the ad hoc test if no test is running.
internal::TestResult* current_test_result(); internal::TestResult* current_test_result();
......
...@@ -468,40 +468,80 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { ...@@ -468,40 +468,80 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
class UnitTestEventListenerInterface { class UnitTestEventListenerInterface {
public: public:
// The d'tor is pure virtual as this is an abstract class. // The d'tor is pure virtual as this is an abstract class.
virtual ~UnitTestEventListenerInterface() = 0; virtual ~UnitTestEventListenerInterface() {}
// Called before the unit test starts. // 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. // 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. // 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. // 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. // 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. // 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. // 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. // 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. // Called before the test starts.
virtual void OnTestStart(const TestInfo*) {} virtual void OnTestStart(const TestInfo& test_info) = 0;
// Called after the test ends. // Called after the test ends.
virtual void OnTestEnd(const TestInfo*) {} virtual void OnTestEnd(const TestInfo& test_info) = 0;
// Called after an assertion. // 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 // The c'tor sets this object as the test part result reporter used by
...@@ -638,7 +678,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( ...@@ -638,7 +678,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
void DefaultGlobalTestPartResultReporter::ReportTestPartResult( void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
const TestPartResult& result) { const TestPartResult& result) {
unit_test_->current_test_result()->AddTestPartResult(result); unit_test_->current_test_result()->AddTestPartResult(result);
unit_test_->result_printer()->OnNewTestPartResult(&result); unit_test_->result_printer()->OnNewTestPartResult(result);
} }
DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
...@@ -1790,6 +1830,19 @@ TestResult::TestResult() ...@@ -1790,6 +1830,19 @@ TestResult::TestResult()
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. // Clears the test part results.
void TestResult::ClearTestPartResults() { void TestResult::ClearTestPartResults() {
test_part_results_->Clear(); test_part_results_->Clear();
...@@ -1887,6 +1940,11 @@ int TestResult::total_part_count() const { ...@@ -1887,6 +1940,11 @@ int TestResult::total_part_count() const {
return test_part_results_->size(); return test_part_results_->size();
} }
// Returns the number of the test properties.
int TestResult::test_property_count() const {
return test_properties_->size();
}
} // namespace internal } // namespace internal
// class Test // class Test
...@@ -2261,7 +2319,7 @@ void TestInfoImpl::Run() { ...@@ -2261,7 +2319,7 @@ void TestInfoImpl::Run() {
// start. // start.
UnitTestEventListenerInterface* const result_printer = UnitTestEventListenerInterface* const result_printer =
impl->result_printer(); impl->result_printer();
result_printer->OnTestStart(parent_); result_printer->OnTestStart(*parent_);
const TimeInMillis start = GetTimeInMillis(); const TimeInMillis start = GetTimeInMillis();
...@@ -2304,7 +2362,7 @@ void TestInfoImpl::Run() { ...@@ -2304,7 +2362,7 @@ void TestInfoImpl::Run() {
result_.set_elapsed_time(GetTimeInMillis() - start); result_.set_elapsed_time(GetTimeInMillis() - start);
// Notifies the unit test event listener that a test has just finished. // 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 // Tells UnitTest to stop associating assertion results to this
// test. // test.
...@@ -2366,6 +2424,12 @@ TestCase::~TestCase() { ...@@ -2366,6 +2424,12 @@ TestCase::~TestCase() {
test_info_list_ = NULL; 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 // Adds a test to this test case. Will delete the test upon
// destruction of the TestCase object. // destruction of the TestCase object.
void TestCase::AddTestInfo(TestInfo * test_info) { void TestCase::AddTestInfo(TestInfo * test_info) {
...@@ -2382,7 +2446,7 @@ void TestCase::Run() { ...@@ -2382,7 +2446,7 @@ void TestCase::Run() {
UnitTestEventListenerInterface * const result_printer = UnitTestEventListenerInterface * const result_printer =
impl->result_printer(); impl->result_printer();
result_printer->OnTestCaseStart(this); result_printer->OnTestCaseStart(*this);
impl->os_stack_trace_getter()->UponLeavingGTest(); impl->os_stack_trace_getter()->UponLeavingGTest();
set_up_tc_(); set_up_tc_();
...@@ -2392,7 +2456,7 @@ void TestCase::Run() { ...@@ -2392,7 +2456,7 @@ void TestCase::Run() {
impl->os_stack_trace_getter()->UponLeavingGTest(); impl->os_stack_trace_getter()->UponLeavingGTest();
tear_down_tc_(); tear_down_tc_();
result_printer->OnTestCaseEnd(this); result_printer->OnTestCaseEnd(*this);
impl->set_current_test_case(NULL); impl->set_current_test_case(NULL);
} }
...@@ -2425,15 +2489,9 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) { ...@@ -2425,15 +2489,9 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
} // namespace internal } // namespace internal
// class UnitTestEventListenerInterface
// The virtual d'tor.
UnitTestEventListenerInterface::~UnitTestEventListenerInterface() {
}
// A result printer that never prints anything. Used in the child process // A result printer that never prints anything. Used in the child process
// of an exec-style death test to avoid needless output clutter. // 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 // Formats a countable noun. Depending on its quantity, either the
// singular form or the plural form is used. e.g. // singular form or the plural form is used. e.g.
...@@ -2628,24 +2686,25 @@ class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface { ...@@ -2628,24 +2686,25 @@ class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface {
// The following methods override what's in the // The following methods override what's in the
// UnitTestEventListenerInterface class. // UnitTestEventListenerInterface class.
virtual void OnUnitTestStart(const UnitTest * unit_test); virtual void OnUnitTestStart(const UnitTest& unit_test);
virtual void OnGlobalSetUpStart(const UnitTest*); virtual void OnGlobalSetUpStart(const UnitTest& unit_test);
virtual void OnTestCaseStart(const TestCase * test_case); virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {}
virtual void OnTestCaseEnd(const TestCase * test_case); virtual void OnTestCaseStart(const TestCase& test_case);
virtual void OnTestStart(const TestInfo * test_info); virtual void OnTestCaseEnd(const TestCase& test_case);
virtual void OnNewTestPartResult(const TestPartResult * result); virtual void OnTestStart(const TestInfo& test_info);
virtual void OnTestEnd(const TestInfo * test_info); virtual void OnNewTestPartResult(const TestPartResult& result);
virtual void OnGlobalTearDownStart(const UnitTest*); virtual void OnTestEnd(const TestInfo& test_info);
virtual void OnUnitTestEnd(const UnitTest * unit_test); virtual void OnGlobalTearDownStart(const UnitTest& unit_test);
virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
virtual void OnUnitTestEnd(const UnitTest& unit_test);
private: private:
internal::String test_case_name_; internal::String test_case_name_;
}; };
// Called before the unit test starts. // Called before the unit test starts.
void PrettyUnitTestResultPrinter::OnUnitTestStart( void PrettyUnitTestResultPrinter::OnUnitTestStart(const UnitTest& unit_test) {
const UnitTest * unit_test) { const char* const filter = GTEST_FLAG(filter).c_str();
const char * const filter = GTEST_FLAG(filter).c_str();
// Prints the filter if it's not *. This reminds the user that some // Prints the filter if it's not *. This reminds the user that some
// tests may be skipped. // tests may be skipped.
...@@ -2661,7 +2720,7 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart( ...@@ -2661,7 +2720,7 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart(
internal::posix::GetEnv(kTestTotalShards)); internal::posix::GetEnv(kTestTotalShards));
} }
const internal::UnitTestImpl* const impl = unit_test->impl(); const internal::UnitTestImpl* const impl = unit_test.impl();
ColoredPrintf(COLOR_GREEN, "[==========] "); ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("Running %s from %s.\n", printf("Running %s from %s.\n",
FormatTestCount(impl->test_to_run_count()).c_str(), FormatTestCount(impl->test_to_run_count()).c_str(),
...@@ -2669,62 +2728,61 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart( ...@@ -2669,62 +2728,61 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart(
fflush(stdout); fflush(stdout);
} }
void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(const UnitTest*) { void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(
const UnitTest& /*unit_test*/) {
ColoredPrintf(COLOR_GREEN, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("Global test environment set-up.\n"); printf("Global test environment set-up.\n");
fflush(stdout); fflush(stdout);
} }
void PrettyUnitTestResultPrinter::OnTestCaseStart( void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
const TestCase * test_case) { test_case_name_ = test_case.name();
test_case_name_ = test_case->name();
const internal::String counts = 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, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s", counts.c_str(), test_case_name_.c_str()); 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"); printf("\n");
} else { } else {
printf(", where %s\n", test_case->comment()); printf(", where %s\n", test_case.comment());
} }
fflush(stdout); fflush(stdout);
} }
void PrettyUnitTestResultPrinter::OnTestCaseEnd( void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
const TestCase * test_case) {
if (!GTEST_FLAG(print_time)) return; if (!GTEST_FLAG(print_time)) return;
test_case_name_ = test_case->name(); test_case_name_ = test_case.name();
const internal::String counts = 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, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s (%s ms total)\n\n", printf("%s from %s (%s ms total)\n\n",
counts.c_str(), test_case_name_.c_str(), 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); fflush(stdout);
} }
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo * test_info) { void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
ColoredPrintf(COLOR_GREEN, "[ RUN ] "); ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
PrintTestName(test_case_name_.c_str(), test_info->name()); PrintTestName(test_case_name_.c_str(), test_info.name());
if (test_info->comment()[0] == '\0') { if (test_info.comment()[0] == '\0') {
printf("\n"); printf("\n");
} else { } else {
printf(", where %s\n", test_info->comment()); printf(", where %s\n", test_info.comment());
} }
fflush(stdout); fflush(stdout);
} }
void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) { void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
if (test_info->result()->Passed()) { if (test_info.result()->Passed()) {
ColoredPrintf(COLOR_GREEN, "[ OK ] "); ColoredPrintf(COLOR_GREEN, "[ OK ] ");
} else { } else {
ColoredPrintf(COLOR_RED, "[ FAILED ] "); 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)) { if (GTEST_FLAG(print_time)) {
printf(" (%s ms)\n", internal::StreamableToString( printf(" (%s ms)\n", internal::StreamableToString(
test_info->result()->elapsed_time()).c_str()); test_info.result()->elapsed_time()).c_str());
} else { } else {
printf("\n"); printf("\n");
} }
...@@ -2733,17 +2791,18 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) { ...@@ -2733,17 +2791,18 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) {
// Called after an assertion failure. // Called after an assertion failure.
void PrettyUnitTestResultPrinter::OnNewTestPartResult( void PrettyUnitTestResultPrinter::OnNewTestPartResult(
const TestPartResult * result) { const TestPartResult& result) {
// If the test part succeeded, we don't need to do anything. // If the test part succeeded, we don't need to do anything.
if (result->type() == TPRT_SUCCESS) if (result.type() == TPRT_SUCCESS)
return; return;
// Print failure message from the assertion (e.g. expected this and got that). // Print failure message from the assertion (e.g. expected this and got that).
PrintTestPartResult(*result); PrintTestPartResult(result);
fflush(stdout); fflush(stdout);
} }
void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(const UnitTest*) { void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(
const UnitTest& /*unit_test*/) {
ColoredPrintf(COLOR_GREEN, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("Global test environment tear-down\n"); printf("Global test environment tear-down\n");
fflush(stdout); fflush(stdout);
...@@ -2788,9 +2847,8 @@ static void PrintFailedTestsPretty(const UnitTestImpl* impl) { ...@@ -2788,9 +2847,8 @@ static void PrintFailedTestsPretty(const UnitTestImpl* impl) {
} // namespace internal } // namespace internal
void PrettyUnitTestResultPrinter::OnUnitTestEnd( void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
const UnitTest * unit_test) { const internal::UnitTestImpl* const impl = unit_test.impl();
const internal::UnitTestImpl* const impl = unit_test->impl();
ColoredPrintf(COLOR_GREEN, "[==========] "); ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("%s from %s ran.", printf("%s from %s ran.",
...@@ -2841,17 +2899,17 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface { ...@@ -2841,17 +2899,17 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
virtual ~UnitTestEventsRepeater(); virtual ~UnitTestEventsRepeater();
void AddListener(UnitTestEventListenerInterface *listener); void AddListener(UnitTestEventListenerInterface *listener);
virtual void OnUnitTestStart(const UnitTest* unit_test); virtual void OnUnitTestStart(const UnitTest& unit_test);
virtual void OnUnitTestEnd(const UnitTest* unit_test); virtual void OnUnitTestEnd(const UnitTest& unit_test);
virtual void OnGlobalSetUpStart(const UnitTest* unit_test); virtual void OnGlobalSetUpStart(const UnitTest& unit_test);
virtual void OnGlobalSetUpEnd(const UnitTest* unit_test); virtual void OnGlobalSetUpEnd(const UnitTest& unit_test);
virtual void OnGlobalTearDownStart(const UnitTest* unit_test); virtual void OnGlobalTearDownStart(const UnitTest& unit_test);
virtual void OnGlobalTearDownEnd(const UnitTest* unit_test); virtual void OnGlobalTearDownEnd(const UnitTest& unit_test);
virtual void OnTestCaseStart(const TestCase* test_case); virtual void OnTestCaseStart(const TestCase& test_case);
virtual void OnTestCaseEnd(const TestCase* test_case); virtual void OnTestCaseEnd(const TestCase& test_case);
virtual void OnTestStart(const TestInfo* test_info); virtual void OnTestStart(const TestInfo& test_info);
virtual void OnTestEnd(const TestInfo* test_info); virtual void OnTestEnd(const TestInfo& test_info);
virtual void OnNewTestPartResult(const TestPartResult* result); virtual void OnNewTestPartResult(const TestPartResult& result);
private: private:
Listeners listeners_; Listeners listeners_;
...@@ -2875,7 +2933,7 @@ void UnitTestEventsRepeater::AddListener( ...@@ -2875,7 +2933,7 @@ void UnitTestEventsRepeater::AddListener(
// Since the methods are identical, use a macro to reduce boilerplate. // Since the methods are identical, use a macro to reduce boilerplate.
// This defines a member that repeats the call to all listeners. // This defines a member that repeats the call to all listeners.
#define GTEST_REPEATER_METHOD_(Name, Type) \ #define GTEST_REPEATER_METHOD_(Name, Type) \
void UnitTestEventsRepeater::Name(const Type* parameter) { \ void UnitTestEventsRepeater::Name(const Type& parameter) { \
for (ListenersNode* listener = listeners_.Head(); \ for (ListenersNode* listener = listeners_.Head(); \
listener != NULL; \ listener != NULL; \
listener = listener->next()) { \ listener = listener->next()) { \
...@@ -2900,11 +2958,11 @@ GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult) ...@@ -2900,11 +2958,11 @@ GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult)
// End PrettyUnitTestResultPrinter // End PrettyUnitTestResultPrinter
// This class generates an XML output file. // This class generates an XML output file.
class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface { class XmlUnitTestResultPrinter : public EmptyTestEventListener {
public: public:
explicit XmlUnitTestResultPrinter(const char* output_file); explicit XmlUnitTestResultPrinter(const char* output_file);
virtual void OnUnitTestEnd(const UnitTest* unit_test); virtual void OnUnitTestEnd(const UnitTest& unit_test);
private: private:
// Is c a whitespace character that is normalized to a space character // Is c a whitespace character that is normalized to a space character
...@@ -2944,7 +3002,7 @@ class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface { ...@@ -2944,7 +3002,7 @@ class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface {
static void PrintXmlTestCase(FILE* out, const TestCase* test_case); static void PrintXmlTestCase(FILE* out, const TestCase* test_case);
// Prints an XML summary of unit_test to output stream out. // 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 // Produces a string representing the test properties in a result as space
// delimited XML attributes based on the property key="value" pairs. // delimited XML attributes based on the property key="value" pairs.
...@@ -2970,7 +3028,7 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) ...@@ -2970,7 +3028,7 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
} }
// Called after the unit test ends. // Called after the unit test ends.
void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) { void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
FILE* xmlout = NULL; FILE* xmlout = NULL;
internal::FilePath output_file(output_file_); internal::FilePath output_file(output_file_);
internal::FilePath output_dir(output_file.RemoveFileName()); internal::FilePath output_dir(output_file.RemoveFileName());
...@@ -3149,8 +3207,8 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, ...@@ -3149,8 +3207,8 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
// Prints an XML summary of unit_test to output stream out. // Prints an XML summary of unit_test to output stream out.
void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
const UnitTest* unit_test) { const UnitTest& unit_test) {
const internal::UnitTestImpl* const impl = unit_test->impl(); const internal::UnitTestImpl* const impl = unit_test.impl();
fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
fprintf(out, fprintf(out,
"<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" " "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
...@@ -3267,6 +3325,64 @@ UnitTest * UnitTest::GetInstance() { ...@@ -3267,6 +3325,64 @@ UnitTest * UnitTest::GetInstance() {
#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) #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 // Registers and returns a global test environment. When a test
// program is run, all global test environments will be set-up in the // program is run, all global test environments will be set-up in the
// order they were registered. After all tests in the program have // order they were registered. After all tests in the program have
...@@ -3683,16 +3799,16 @@ int UnitTestImpl::RunAllTests() { ...@@ -3683,16 +3799,16 @@ int UnitTestImpl::RunAllTests() {
// Tells the unit test event listener that the tests are about to // Tells the unit test event listener that the tests are about to
// start. // start.
printer->OnUnitTestStart(parent_); printer->OnUnitTestStart(*parent_);
const TimeInMillis start = GetTimeInMillis(); const TimeInMillis start = GetTimeInMillis();
// Runs each test case if there is at least one test to run. // Runs each test case if there is at least one test to run.
if (has_tests_to_run) { if (has_tests_to_run) {
// Sets up all environments beforehand. // Sets up all environments beforehand.
printer->OnGlobalSetUpStart(parent_); printer->OnGlobalSetUpStart(*parent_);
environments_.ForEach(SetUpEnvironment); environments_.ForEach(SetUpEnvironment);
printer->OnGlobalSetUpEnd(parent_); printer->OnGlobalSetUpEnd(*parent_);
// Runs the tests only if there was no fatal failure during global // Runs the tests only if there was no fatal failure during global
// set-up. // set-up.
...@@ -3701,16 +3817,16 @@ int UnitTestImpl::RunAllTests() { ...@@ -3701,16 +3817,16 @@ int UnitTestImpl::RunAllTests() {
} }
// Tears down all environments in reverse order afterwards. // Tears down all environments in reverse order afterwards.
printer->OnGlobalTearDownStart(parent_); printer->OnGlobalTearDownStart(*parent_);
environments_in_reverse_order_.ForEach(TearDownEnvironment); environments_in_reverse_order_.ForEach(TearDownEnvironment);
printer->OnGlobalTearDownEnd(parent_); printer->OnGlobalTearDownEnd(*parent_);
} }
elapsed_time_ = GetTimeInMillis() - start; elapsed_time_ = GetTimeInMillis() - start;
// Tells the unit test event listener that the tests have just // Tells the unit test event listener that the tests have just
// finished. // finished.
printer->OnUnitTestEnd(parent_); printer->OnUnitTestEnd(*parent_);
// Gets the result and clears it. // Gets the result and clears it.
if (!Passed()) { if (!Passed()) {
......
...@@ -148,7 +148,6 @@ using testing::internal::String; ...@@ -148,7 +148,6 @@ using testing::internal::String;
using testing::internal::TestProperty; using testing::internal::TestProperty;
using testing::internal::TestResult; using testing::internal::TestResult;
using testing::internal::ThreadLocal; using testing::internal::ThreadLocal;
using testing::internal::UnitTestImpl;
using testing::internal::WideStringToUtf8; using testing::internal::WideStringToUtf8;
// This line tests that we can define tests in an unnamed namespace. // This line tests that we can define tests in an unnamed namespace.
...@@ -526,6 +525,19 @@ TEST(ListTest, InsertAfterNotAtBeginning) { ...@@ -526,6 +525,19 @@ TEST(ListTest, InsertAfterNotAtBeginning) {
EXPECT_EQ(3, a.Last()->element()); 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. // Tests the String class.
...@@ -1085,23 +1097,38 @@ class TestResultTest : public Test { ...@@ -1085,23 +1097,38 @@ class TestResultTest : public Test {
delete r1; delete r1;
delete r2; 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) { TEST_F(TestResultTest, test_part_results) {
ASSERT_EQ(0u, r0->test_part_results().size()); ASSERT_EQ(0u, r0->test_part_results().size());
ASSERT_EQ(1u, r1->test_part_results().size()); ASSERT_EQ(1u, r1->test_part_results().size());
ASSERT_EQ(2u, r2->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) { TEST_F(TestResultTest, successful_part_count) {
ASSERT_EQ(0u, r0->successful_part_count()); ASSERT_EQ(0u, r0->successful_part_count());
ASSERT_EQ(1u, r1->successful_part_count()); ASSERT_EQ(1u, r1->successful_part_count());
ASSERT_EQ(1u, r2->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) { TEST_F(TestResultTest, failed_part_count) {
ASSERT_EQ(0u, r0->failed_part_count()); ASSERT_EQ(0u, r0->failed_part_count());
ASSERT_EQ(0u, r1->failed_part_count()); ASSERT_EQ(0u, r1->failed_part_count());
...@@ -1115,27 +1142,35 @@ TEST_F(TestResultTest, GetFailedPartCount) { ...@@ -1115,27 +1142,35 @@ TEST_F(TestResultTest, GetFailedPartCount) {
ASSERT_EQ(1u, GetFailedPartCount(r2)); ASSERT_EQ(1u, GetFailedPartCount(r2));
} }
// Tests TestResult::total_part_count() // Tests TestResult::total_part_count().
TEST_F(TestResultTest, total_part_count) { TEST_F(TestResultTest, total_part_count) {
ASSERT_EQ(0u, r0->total_part_count()); ASSERT_EQ(0u, r0->total_part_count());
ASSERT_EQ(1u, r1->total_part_count()); ASSERT_EQ(1u, r1->total_part_count());
ASSERT_EQ(2u, r2->total_part_count()); ASSERT_EQ(2u, r2->total_part_count());
} }
// Tests TestResult::Passed() // Tests TestResult::Passed().
TEST_F(TestResultTest, Passed) { TEST_F(TestResultTest, Passed) {
ASSERT_TRUE(r0->Passed()); ASSERT_TRUE(r0->Passed());
ASSERT_TRUE(r1->Passed()); ASSERT_TRUE(r1->Passed());
ASSERT_FALSE(r2->Passed()); ASSERT_FALSE(r2->Passed());
} }
// Tests TestResult::Failed() // Tests TestResult::Failed().
TEST_F(TestResultTest, Failed) { TEST_F(TestResultTest, Failed) {
ASSERT_FALSE(r0->Failed()); ASSERT_FALSE(r0->Failed());
ASSERT_FALSE(r1->Failed()); ASSERT_FALSE(r1->Failed());
ASSERT_TRUE(r2->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. // Tests TestResult::test_properties() has no properties when none are added.
TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) {
TestResult test_result; TestResult test_result;
...@@ -1195,6 +1230,49 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { ...@@ -1195,6 +1230,49 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) {
EXPECT_STREQ("22", actual_property_2.value()); 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 // 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 // that a non-fatal failure is added, a fatal failure is not added, and that the
// property is not recorded. // property is not recorded.
...@@ -3061,6 +3139,10 @@ TEST(AssertionTest, ASSERT_EQ) { ...@@ -3061,6 +3139,10 @@ TEST(AssertionTest, ASSERT_EQ) {
TEST(AssertionTest, ASSERT_EQ_NULL) { TEST(AssertionTest, ASSERT_EQ_NULL) {
// A success. // A success.
const char* p = NULL; 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); ASSERT_EQ(NULL, p);
// A failure. // A failure.
...@@ -3614,6 +3696,10 @@ TEST(ExpectTest, EXPECT_EQ_Double) { ...@@ -3614,6 +3696,10 @@ TEST(ExpectTest, EXPECT_EQ_Double) {
TEST(ExpectTest, EXPECT_EQ_NULL) { TEST(ExpectTest, EXPECT_EQ_NULL) {
// A success. // A success.
const char* p = NULL; 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); EXPECT_EQ(NULL, p);
// A failure. // A failure.
...@@ -5207,7 +5293,7 @@ class CurrentTestInfoTest : public Test { ...@@ -5207,7 +5293,7 @@ class CurrentTestInfoTest : public Test {
// There should be no tests running at this point. // There should be no tests running at this point.
const TestInfo* test_info = const TestInfo* test_info =
UnitTest::GetInstance()->current_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."; << "There should be no tests running at this point.";
} }
...@@ -5216,7 +5302,7 @@ class CurrentTestInfoTest : public Test { ...@@ -5216,7 +5302,7 @@ class CurrentTestInfoTest : public Test {
static void TearDownTestCase() { static void TearDownTestCase() {
const TestInfo* test_info = const TestInfo* test_info =
UnitTest::GetInstance()->current_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."; << "There should be no tests running at this point.";
} }
}; };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment