Commit e6095dee by zhanyong.wan

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

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 {
// 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;
......
......@@ -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_
......
......@@ -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_
......
......@@ -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();
......
......@@ -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.";
}
};
......
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