From e6095deec89dcf5237948b3460d84a137622f16c Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 24 Jun 2009 23:02:50 +0000 Subject: [PATCH] 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). --- include/gtest/gtest.h | 59 +++++ include/gtest/internal/gtest-tuple.h | 79 +++--- include/gtest/internal/gtest-tuple.h.pump | 25 +- src/gtest-internal-inl.h | 26 ++ src/gtest.cc | 292 +++++++++++++++------- test/gtest_unittest.cc | 104 +++++++- 6 files changed, 454 insertions(+), 131 deletions(-) diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h index 66653d1c..2b1c9782 100644 --- a/include/gtest/gtest.h +++ b/include/gtest/gtest.h @@ -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; diff --git a/include/gtest/internal/gtest-tuple.h b/include/gtest/internal/gtest-tuple.h index be23e8eb..5ef49203 100644 --- a/include/gtest/internal/gtest-tuple.h +++ b/include/gtest/internal/gtest-tuple.h @@ -38,18 +38,38 @@ #include // 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 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 -#define GTEST_2_TUPLE_(T) tuple -#define GTEST_3_TUPLE_(T) tuple -#define GTEST_4_TUPLE_(T) tuple -#define GTEST_5_TUPLE_(T) tuple -#define GTEST_6_TUPLE_(T) tuple -#define GTEST_7_TUPLE_(T) tuple -#define GTEST_8_TUPLE_(T) tuple +#define GTEST_1_TUPLE_(T) tuple +#define GTEST_2_TUPLE_(T) tuple +#define GTEST_3_TUPLE_(T) tuple +#define GTEST_4_TUPLE_(T) tuple +#define GTEST_5_TUPLE_(T) tuple +#define GTEST_6_TUPLE_(T) tuple +#define GTEST_7_TUPLE_(T) tuple +#define GTEST_8_TUPLE_(T) tuple #define GTEST_9_TUPLE_(T) tuple + T##7, T##8, void> #define GTEST_10_TUPLE_(T) tuple @@ -162,7 +182,6 @@ template class GTEST_1_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -180,7 +199,8 @@ class GTEST_1_TUPLE_(T) { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { f0_ = t.f0_; @@ -194,7 +214,6 @@ template class GTEST_2_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -221,7 +240,8 @@ class GTEST_2_TUPLE_(T) { return *this; } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { f0_ = t.f0_; @@ -237,7 +257,6 @@ template class GTEST_3_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -256,7 +275,8 @@ class GTEST_3_TUPLE_(T) { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { f0_ = t.f0_; @@ -274,7 +294,6 @@ template class GTEST_4_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -295,7 +314,8 @@ class GTEST_4_TUPLE_(T) { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { f0_ = t.f0_; @@ -315,7 +335,6 @@ template class GTEST_5_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -337,7 +356,8 @@ class GTEST_5_TUPLE_(T) { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { f0_ = t.f0_; @@ -359,7 +379,6 @@ template class GTEST_6_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -382,7 +401,8 @@ class GTEST_6_TUPLE_(T) { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { f0_ = t.f0_; @@ -406,7 +426,6 @@ template class GTEST_7_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -429,7 +448,8 @@ class GTEST_7_TUPLE_(T) { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { f0_ = t.f0_; @@ -455,7 +475,6 @@ template class GTEST_8_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -479,7 +498,8 @@ class GTEST_8_TUPLE_(T) { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { f0_ = t.f0_; @@ -507,7 +527,6 @@ template class GTEST_9_TUPLE_(T) { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -531,7 +550,8 @@ class GTEST_9_TUPLE_(T) { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { f0_ = t.f0_; @@ -561,7 +581,6 @@ template class tuple { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -586,7 +605,8 @@ class tuple { return CopyFrom(t); } - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template 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_ diff --git a/include/gtest/internal/gtest-tuple.h.pump b/include/gtest/internal/gtest-tuple.h.pump index 33fd6b6d..12821d8b 100644 --- a/include/gtest/internal/gtest-tuple.h.pump +++ b/include/gtest/internal/gtest-tuple.h.pump @@ -39,15 +39,29 @@ $$ This meta comment fixes auto-indentation in Emacs. }} #include // 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 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 class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { public: template friend class gtest_internal::Get; - template friend class tuple; tuple() {} @@ -160,7 +173,8 @@ $if k == 2 [[ ]] - private: + GTEST_DECLARE_TUPLE_AS_FRIEND_ + template 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_ diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h index 589be02e..3abe9a26 100644 --- a/src/gtest-internal-inl.h +++ b/src/gtest-internal-inl.h @@ -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* 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* head_; // The first node of the list. ListNode* 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(); diff --git a/src/gtest.cc b/src/gtest.cc index f5b05b2d..ec176918 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -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, "\n"); fprintf(out, "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()) { diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index fe452f42..b1a161bb 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -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 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."; } };