From ed8500b341c473ecf46acd13951ae5b4e3acc780 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 7 Aug 2009 06:47:47 +0000 Subject: Implements EXPECT_DEATH_IF_SUPPORTED (by Vlad Losev); Fixes compatibility with Symbian (by Araceli Checa); Removes GetCapturedStderr()'s dependency on std::string (by Vlad Losev). --- include/gtest/gtest-death-test.h | 22 ++++++++++++++++++ include/gtest/internal/gtest-port.h | 4 +--- include/gtest/internal/gtest-tuple.h | 10 ++++---- src/gtest-death-test.cc | 8 ++----- src/gtest-port.cc | 12 ++++------ test/gtest-death-test_test.cc | 38 +++++++++++++++++++++++++++++++ test/gtest-port_test.cc | 6 +---- test/gtest_unittest.cc | 44 ++++++++++++------------------------ 8 files changed, 88 insertions(+), 56 deletions(-) diff --git a/include/gtest/gtest-death-test.h b/include/gtest/gtest-death-test.h index dcb2b66..410654b 100644 --- a/include/gtest/gtest-death-test.h +++ b/include/gtest/gtest-death-test.h @@ -257,6 +257,28 @@ class KilledBySignal { #endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they expand to empty. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_LOG_(WARNING, \ + "Death tests are not supported on this platform. The statement" \ + " '" #statement "' can not be verified") +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_LOG_(WARNING, \ + "Death tests are not supported on this platform. The statement" \ + " '" #statement "' can not be verified") +#endif + } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h index e67a498..58b2eaf 100644 --- a/include/gtest/internal/gtest-port.h +++ b/include/gtest/internal/gtest-port.h @@ -696,10 +696,8 @@ inline void FlushInfoLog() { fflush(NULL); } // CaptureStderr - starts capturing stderr. // GetCapturedStderr - stops capturing stderr and returns the captured string. -#if GTEST_HAS_STD_STRING void CaptureStderr(); -::std::string GetCapturedStderr(); -#endif // GTEST_HAS_STD_STRING +String GetCapturedStderr(); #if GTEST_HAS_DEATH_TEST diff --git a/include/gtest/internal/gtest-tuple.h b/include/gtest/internal/gtest-tuple.h index 5ef4920..86b200b 100644 --- a/include/gtest/internal/gtest-tuple.h +++ b/include/gtest/internal/gtest-tuple.h @@ -38,11 +38,11 @@ #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__ +// The compiler used in Symbian 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__) #define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else #define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc index 0d4110b..02ce48d 100644 --- a/src/gtest-death-test.cc +++ b/src/gtest-death-test.cc @@ -452,11 +452,7 @@ bool DeathTestImpl::Passed(bool status_ok) { if (!spawned()) return false; -#if GTEST_HAS_GLOBAL_STRING - const ::string error_message = GetCapturedStderr(); -#else - const ::std::string error_message = GetCapturedStderr(); -#endif // GTEST_HAS_GLOBAL_STRING + const String error_message = GetCapturedStderr(); bool success = false; Message buffer; @@ -473,7 +469,7 @@ bool DeathTestImpl::Passed(bool status_ok) { break; case DIED: if (status_ok) { - if (RE::PartialMatch(error_message, *regex())) { + if (RE::PartialMatch(error_message.c_str(), *regex())) { success = true; } else { buffer << " Result: died but not with expected error.\n" diff --git a/src/gtest-port.cc b/src/gtest-port.cc index bc6d8f8..09d1a8e 100644 --- a/src/gtest-port.cc +++ b/src/gtest-port.cc @@ -431,8 +431,6 @@ void GTestLog(GTestLogSeverity severity, const char* file, } } -#if GTEST_HAS_STD_STRING - // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) #ifdef _MSC_VER @@ -514,7 +512,7 @@ static size_t GetFileSize(FILE * file) { } // Reads the entire content of a file as a string. -static ::std::string ReadEntireFile(FILE * file) { +static String ReadEntireFile(FILE * file) { const size_t file_size = GetFileSize(file); char* const buffer = new char[file_size]; @@ -530,7 +528,7 @@ static ::std::string ReadEntireFile(FILE * file) { bytes_read += bytes_last_read; } while (bytes_last_read > 0 && bytes_read < file_size); - const ::std::string content(buffer, buffer+bytes_read); + const String content(buffer, bytes_read); delete[] buffer; return content; @@ -547,11 +545,11 @@ void CaptureStderr() { // Stops capturing stderr and returns the captured string. // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can // use it here. -::std::string GetCapturedStderr() { +String GetCapturedStderr() { g_captured_stderr->StopCapture(); FILE* const file = posix::FOpen(g_captured_stderr->filename().c_str(), "r"); - const ::std::string content = ReadEntireFile(file); + const String content = ReadEntireFile(file); posix::FClose(file); delete g_captured_stderr; @@ -560,8 +558,6 @@ void CaptureStderr() { return content; } -#endif // GTEST_HAS_STD_STRING - #if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index d5f1598..1881139 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -1118,6 +1118,44 @@ TEST(EnvironmentTest, HandleFitsIntoSizeT) { } #endif // GTEST_OS_WINDOWS +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger +// failures when death tests are available on the system. +TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { + EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(false) << "failure", "false.*failure"); + ASSERT_DEATH_IF_SUPPORTED(GTEST_CHECK_(false) << "failure", "false.*failure"); + + // Empty statement will not crash, which must trigger a failure. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); + EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); +} + +#else + +using testing::internal::CaptureStderr; +using testing::internal::GetCapturedStderr; +using testing::internal::String; + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still +// defined but do not rigger failures when death tests are not available on +// the system. +TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { + // Empty statement will not crash, but that should not trigger a failure + // when death tests are not supported. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, ""); + String output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, ""); + output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); +} + #endif // GTEST_HAS_DEATH_TEST // Tests that a test case whose name ends with "DeathTest" works fine diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 49af8b9..d980b7c 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -688,15 +688,11 @@ TEST(RETest, PartialMatchWorks) { #endif // GTEST_USES_POSIX_RE -#if GTEST_HAS_STD_STRING - TEST(CaptureStderrTest, CapturesStdErr) { CaptureStderr(); fprintf(stderr, "abc"); - ASSERT_EQ("abc", GetCapturedStderr()); + ASSERT_STREQ("abc", GetCapturedStderr().c_str()); } -#endif // GTEST_HAS_STD_STRING - } // namespace internal } // namespace testing diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 4eb098e..2c08720 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -78,16 +78,6 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #endif -// GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) expands to a -// real death test if death tests are supported; otherwise it expands -// to empty. -#if GTEST_HAS_DEATH_TEST -#define GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) \ - EXPECT_DEATH(statement, regex) -#else -#define GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) -#endif - namespace testing { namespace internal { const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); @@ -630,7 +620,7 @@ TEST(VectorDeathTest, Erase) { Vector a; // Tests erasing from an empty vector. - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a.Erase(0), "Invalid Vector index 0: must be in range \\[0, -1\\]\\."); @@ -646,10 +636,10 @@ TEST(VectorDeathTest, Erase) { a1.PushBack(1); a1.PushBack(2); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a1.Erase(3), "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a1.Erase(-1), "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); @@ -697,10 +687,10 @@ TEST(ListDeathTest, GetElement) { EXPECT_EQ(0, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(1)); EXPECT_EQ(2, a.GetElement(2)); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a.GetElement(3), "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a.GetElement(-1), "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } @@ -1368,10 +1358,10 @@ typedef TestResultTest TestResultDeathTest; TEST_F(TestResultDeathTest, GetTestPartResult) { CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( r2->GetTestPartResult(2), "Invalid Vector index 2: must be in range \\[0, 1\\]\\."); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( r2->GetTestPartResult(-1), "Invalid Vector index -1: must be in range \\[0, 1\\]\\."); } @@ -1455,10 +1445,10 @@ TEST(TestResultPropertyDeathTest, GetTestProperty) { EXPECT_STREQ("key_3", fetched_property_3.key()); EXPECT_STREQ("3", fetched_property_3.value()); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( test_result.GetTestProperty(3), "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( test_result.GetTestProperty(-1), "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } @@ -1737,7 +1727,7 @@ TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { // if the variable is not an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), ".*"); } @@ -1746,7 +1736,7 @@ TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { // if the variable cannot be represnted by an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), ".*"); } @@ -1824,23 +1814,19 @@ typedef ShouldShardTest ShouldShardDeathTest; TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) { SetEnv(index_var_, "4"); SetEnv(total_var_, "4"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), - ".*"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, "4"); SetEnv(total_var_, "-2"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), - ".*"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, "5"); SetEnv(total_var_, ""); - GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), - ".*"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, ""); SetEnv(total_var_, "5"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), - ".*"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); } // Tests that ShouldRunTestOnShard is a partition when 5 -- cgit v0.12