]> git-server-git.apps.pok.os.sepia.ceph.com Git - googletest.git/commitdiff
Adds exception assertions. By balaz.dan@gmail.com.
authorshiqian <shiqian@861a406c-534a-0410-8894-cb66d6ee9925>
Fri, 12 Sep 2008 20:57:22 +0000 (20:57 +0000)
committershiqian <shiqian@861a406c-534a-0410-8894-cb66d6ee9925>
Fri, 12 Sep 2008 20:57:22 +0000 (20:57 +0000)
include/gtest/gtest.h
include/gtest/internal/gtest-internal.h
test/gtest_unittest.cc

index 057efa26e36eda506cbe5dd5df8c9176b860ae1a..67cf4ac0ae7f1c6b3356ff0384f20d0d5fd7b379 100644 (file)
@@ -928,6 +928,28 @@ class AssertHelper {
 // Generates a success with a generic message.
 #define SUCCEED() GTEST_SUCCESS("Succeeded")
 
+// Macros for testing exceptions.
+//
+//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):
+//         Tests that the statement throws the expected exception.
+//    * {ASSERT|EXPECT}_NO_THROW(statement):
+//         Tests that the statement doesn't throw any exception.
+//    * {ASSERT|EXPECT}_ANY_THROW(statement):
+//         Tests that the statement throws an exception.
+
+#define EXPECT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW(statement, expected_exception, GTEST_NONFATAL_FAILURE)
+#define EXPECT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW(statement, GTEST_NONFATAL_FAILURE)
+#define EXPECT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW(statement, GTEST_NONFATAL_FAILURE)
+#define ASSERT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW(statement, expected_exception, GTEST_FATAL_FAILURE)
+#define ASSERT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW(statement, GTEST_FATAL_FAILURE)
+#define ASSERT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW(statement, GTEST_FATAL_FAILURE)
+
 // Boolean assertions.
 #define EXPECT_TRUE(condition) \
   GTEST_TEST_BOOLEAN(condition, #condition, false, true, \
index 8adf13e42bc6e2824e0992755c4affa5bac6e24f..898047e803514a6475f09d7ea3c3eaf3568002ba 100644 (file)
@@ -717,6 +717,67 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
 #define GTEST_SUCCESS(message) \
   GTEST_MESSAGE(message, ::testing::TPRT_SUCCESS)
 
+
+#define GTEST_TEST_THROW(statement, expected_exception, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER \
+  if (const char* gtest_msg = "") { \
+    bool gtest_caught_expected = false; \
+    try { \
+      statement; \
+    } \
+    catch (expected_exception const&) { \
+      gtest_caught_expected = true; \
+    } \
+    catch (...) { \
+      gtest_msg = "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 = "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)
+
+#define GTEST_TEST_NO_THROW(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER \
+  if (const char* gtest_msg = "") { \
+    try { \
+      statement; \
+    } \
+    catch (...) { \
+      gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \
+                  "  Actual: it throws."; \
+      goto GTEST_CONCAT_TOKEN(gtest_label_testnothrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN(gtest_label_testnothrow_, __LINE__): \
+      fail(gtest_msg)
+
+#define GTEST_TEST_ANY_THROW(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER \
+  if (const char* gtest_msg = "") { \
+    bool gtest_caught_any = false; \
+    try { \
+      statement; \
+    } \
+    catch (...) { \
+      gtest_caught_any = true; \
+    } \
+    if (!gtest_caught_any) { \
+      gtest_msg = "Expected: " #statement " throws an exception.\n" \
+                  "  Actual: it doesn't."; \
+      goto GTEST_CONCAT_TOKEN(gtest_label_testanythrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN(gtest_label_testanythrow_, __LINE__): \
+      fail(gtest_msg)
+
+
 #define GTEST_TEST_BOOLEAN(boolexpr, booltext, actual, expected, fail) \
   GTEST_AMBIGUOUS_ELSE_BLOCKER \
   if (boolexpr) \
index 8343795aa90cfeb4eb4f27eb1e2ad41328bc4ad7..b20b98c1c89ef00f0475c723255f8aacd74258cd 100644 (file)
@@ -2314,6 +2314,56 @@ TEST_F(SingleEvaluationTest, OtherCases) {
   EXPECT_EQ(3, b_);
 }
 
+#if GTEST_HAS_EXCEPTIONS
+
+void ThrowAnInteger() {
+  throw 1;
+}
+
+// Tests that assertion arguments are evaluated exactly once.
+TEST_F(SingleEvaluationTest, ExceptionTests) {
+  // successful EXPECT_THROW
+  EXPECT_THROW({  // NOLINT
+    a_++;
+    ThrowAnInteger();
+  }, int);
+  EXPECT_EQ(1, a_);
+
+  // failed EXPECT_THROW, throws different
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW({  // NOLINT
+    a_++;
+    ThrowAnInteger();
+  }, bool), "throws a different type");
+  EXPECT_EQ(2, a_);
+
+  // failed EXPECT_THROW, throws nothing
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(a_++, bool), "throws nothing");
+  EXPECT_EQ(3, a_);
+
+  // successful EXPECT_NO_THROW
+  EXPECT_NO_THROW(a_++);
+  EXPECT_EQ(4, a_);
+
+  // failed EXPECT_NO_THROW
+  EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW({  // NOLINT
+    a_++;
+    ThrowAnInteger();
+  }), "it throws");
+  EXPECT_EQ(5, a_);
+
+  // successful EXPECT_ANY_THROW
+  EXPECT_ANY_THROW({  // NOLINT
+    a_++;
+    ThrowAnInteger();
+  });
+  EXPECT_EQ(6, a_);
+
+  // failed EXPECT_ANY_THROW
+  EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(a_++), "it doesn't");
+  EXPECT_EQ(7, a_);
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
 
 // Tests non-string assertions.
 
@@ -2487,6 +2537,37 @@ TEST(AssertionTest, ASSERT_GT) {
                        "Expected: (2) > (2), actual: 2 vs 2");
 }
 
+#if GTEST_HAS_EXCEPTIONS
+
+// Tests ASSERT_THROW.
+TEST(AssertionTest, ASSERT_THROW) {
+  ASSERT_THROW(ThrowAnInteger(), int);
+  EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool),
+                       "Expected: ThrowAnInteger() throws an exception of type"\
+                       " bool.\n  Actual: it throws a different type.");
+  EXPECT_FATAL_FAILURE(ASSERT_THROW(1, bool),
+                       "Expected: 1 throws an exception of type bool.\n"\
+                       "  Actual: it throws nothing.");
+}
+
+// Tests ASSERT_NO_THROW.
+TEST(AssertionTest, ASSERT_NO_THROW) {
+  ASSERT_NO_THROW(1);
+  EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()),
+                       "Expected: ThrowAnInteger() doesn't throw an exception."\
+                       "\n  Actual: it throws.");
+}
+
+// Tests ASSERT_ANY_THROW.
+TEST(AssertionTest, ASSERT_ANY_THROW) {
+  ASSERT_ANY_THROW(ThrowAnInteger());
+  EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(1),
+                       "Expected: 1 throws an exception.\n  Actual: it "\
+                       "doesn't.");
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
 // Makes sure we deal with the precedence of <<.  This test should
 // compile.
 TEST(AssertionTest, AssertPrecedence) {
@@ -2764,6 +2845,32 @@ TEST(AssertionSyntaxTest, BehavesLikeSingleStatement) {
     ;
   else
     EXPECT_GT(3, 2) << "";
+
+#if GTEST_HAS_EXCEPTIONS
+  if (false)
+    EXPECT_THROW(1, bool);
+
+  if (true)
+    EXPECT_THROW(ThrowAnInteger(), int);
+  else
+    ;
+
+  if (false)
+    EXPECT_NO_THROW(ThrowAnInteger());
+
+  if (true)
+    EXPECT_NO_THROW(1);
+  else
+    ;
+
+  if (false)
+    EXPECT_ANY_THROW(1);
+
+  if (true)
+    EXPECT_ANY_THROW(ThrowAnInteger());
+  else
+    ;
+#endif  // GTEST_HAS_EXCEPTIONS
 }
 
 // Tests that the assertion macros work well with switch statements.
@@ -2792,6 +2899,22 @@ TEST(AssertionSyntaxTest, WorksWithSwitch) {
       EXPECT_NE(1, 2);
 }
 
+#if GTEST_HAS_EXCEPTIONS
+
+void ThrowAString() {
+    throw "String";
+}
+
+// Test that the exception assertion macros compile and work with const
+// type qualifier.
+TEST(AssertionSyntaxTest, WorksWithConst) {
+    ASSERT_THROW(ThrowAString(), const char*);
+
+    EXPECT_THROW(ThrowAString(), const char*);
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
 }  // namespace
 
 // Returns the number of successful parts in the current test.
@@ -2971,6 +3094,37 @@ TEST(ExpectTest, EXPECT_GT) {
                           "(2) > (3)");
 }
 
+#if GTEST_HAS_EXCEPTIONS
+
+// Tests EXPECT_THROW.
+TEST(ExpectTest, EXPECT_THROW) {
+  EXPECT_THROW(ThrowAnInteger(), int);
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool),
+                          "Expected: ThrowAnInteger() throws an exception of "\
+                          "type bool.\n  Actual: it throws a different type.");
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(1, bool),
+                          "Expected: 1 throws an exception of type bool.\n"\
+                          "  Actual: it throws nothing.");
+}
+
+// Tests EXPECT_NO_THROW.
+TEST(ExpectTest, EXPECT_NO_THROW) {
+  EXPECT_NO_THROW(1);
+  EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()),
+                          "Expected: ThrowAnInteger() doesn't throw an "\
+                          "exception.\n  Actual: it throws.");
+}
+
+// Tests EXPECT_ANY_THROW.
+TEST(ExpectTest, EXPECT_ANY_THROW) {
+  EXPECT_ANY_THROW(ThrowAnInteger());
+  EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(1),
+                          "Expected: 1 throws an exception.\n  Actual: it "\
+                          "doesn't.");
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
 // Make sure we deal with the precedence of <<.
 TEST(ExpectTest, ExpectPrecedence) {
   EXPECT_EQ(1 < 2, true);
@@ -4477,6 +4631,37 @@ TEST(StreamingAssertionsTest, FloatingPointEquals) {
                        "expected failure");
 }
 
+#if GTEST_HAS_EXCEPTIONS
+
+TEST(StreamingAssertionsTest, Throw) {
+  EXPECT_THROW(ThrowAnInteger(), int) << "unexpected failure";
+  ASSERT_THROW(ThrowAnInteger(), int) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool) <<
+                          "expected failure", "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool) <<
+                       "expected failure", "expected failure");
+}
+
+TEST(StreamingAssertionsTest, NoThrow) {
+  EXPECT_NO_THROW(1) << "unexpected failure";
+  ASSERT_NO_THROW(1) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) <<
+                          "expected failure", "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) <<
+                       "expected failure", "expected failure");
+}
+
+TEST(StreamingAssertionsTest, AnyThrow) {
+  EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure";
+  ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(1) <<
+                          "expected failure", "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(1) <<
+                       "expected failure", "expected failure");
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
 // Tests that Google Test correctly decides whether to use colors in the output.
 
 TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) {