From 0d2262138c63e8c5ae8f00286e016e4df5e716be Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 4 Sep 2018 17:27:33 -0400 Subject: [PATCH] Googletest export Make EXPECT_THROW print the actual exception type on the "threw the wrong exception type" case if the actual exception is a std::exception PiperOrigin-RevId: 211524592 --- .../include/gtest/internal/gtest-internal.h | 75 ++++++++----------- googletest/test/gtest_unittest.cc | 9 --- 2 files changed, 31 insertions(+), 53 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 60c79647..b762f61f 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -771,12 +771,13 @@ GTEST_API_ bool AlwaysTrue(); // Always returns false. inline bool AlwaysFalse() { return !AlwaysTrue(); } -// Helper for creating strings in if() statement branches. Always converts to -// true. -struct GTEST_API_ TrueString { - TrueString() {} +// Helper for suppressing false warning from Clang on a const char* +// variable declared in a conditional expression always being NULL in +// the else branch. +struct GTEST_API_ ConstCharPtr { + ConstCharPtr(const char* str) : value(str) {} operator bool() const { return true; } - std::string value; + const char* value; }; // A simple Linear Congruential Generator for generating random @@ -1213,45 +1214,31 @@ class NativeArray { #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ if (::testing::internal::AlwaysTrue()) { statement; } -#define GTEST_WRONG_EXCEPTION_MESSAGE_(statement, expected_exception) \ - "Expected: " #statement " throws an exception of type " #expected_exception \ - ".\n Actual: it throws " - -// The nested try-catch block allows us to catch erroneous exceptions which -// inherit from std::exception and feed what() to the failure description. If -// there was no nested try-catch and expected_exception was std::exception, then -// this would fail to build due to two blocks both catching std::exceptions. -#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::TrueString gtest_msg = \ - ::testing::internal::TrueString()) { \ - bool gtest_caught_expected = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (expected_exception const&) { \ - gtest_caught_expected = true; \ - } catch (...) { \ - try { \ - throw; \ - } catch (const std::exception& e) { \ - gtest_msg.value = std::string(GTEST_WRONG_EXCEPTION_MESSAGE_( \ - statement, expected_expression)) + \ - e.what() + "."; \ - } catch (...) { \ - gtest_msg.value = GTEST_WRONG_EXCEPTION_MESSAGE_( \ - statement, expected_exception) "a different type."; \ - } \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - if (!gtest_caught_expected) { \ - gtest_msg.value = "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws nothing."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ - : fail(gtest_msg.value.c_str()) +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::ConstCharPtr gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg.value) #define GTEST_TEST_NO_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 3965f46b..f7213fbf 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -4541,21 +4541,12 @@ TEST(ExpectTest, EXPECT_THROW) { EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool), "Expected: ThrowAnInteger() throws an exception of " "type bool.\n Actual: it throws a different type."); - std::string expected = "what() arg"; - EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw std::out_of_range(expected), bool), - expected); EXPECT_NONFATAL_FAILURE( EXPECT_THROW(ThrowNothing(), bool), "Expected: ThrowNothing() throws an exception of type bool.\n" " Actual: it throws nothing."); } -// We need to make sure always to avoid having multiple blocks which catch a -// std::exception -TEST(ExpectTest, EXPECT_THROW_STD_EXCEPTION) { - EXPECT_THROW(throw std::exception(), std::exception); -} - // Tests EXPECT_NO_THROW. TEST(ExpectTest, EXPECT_NO_THROW) { EXPECT_NO_THROW(ThrowNothing());