diff --git a/docs/reference/assertions.md b/docs/reference/assertions.md index 492ff5ef..eeec4a0c 100644 --- a/docs/reference/assertions.md +++ b/docs/reference/assertions.md @@ -276,7 +276,8 @@ Units in the Last Place (ULPs). To learn more about ULPs, see the article `ASSERT_FLOAT_EQ(`*`val1`*`,`*`val2`*`)` Verifies that the two `float` values *`val1`* and *`val2`* are approximately -equal, to within 4 ULPs from each other. +equal, to within 4 ULPs from each other. Infinity and the largest finite float +value are considered to be one ULP apart. ### EXPECT_DOUBLE_EQ {#EXPECT_DOUBLE_EQ} @@ -284,7 +285,8 @@ equal, to within 4 ULPs from each other. `ASSERT_DOUBLE_EQ(`*`val1`*`,`*`val2`*`)` Verifies that the two `double` values *`val1`* and *`val2`* are approximately -equal, to within 4 ULPs from each other. +equal, to within 4 ULPs from each other. Infinity and the largest finite double +value are considered to be one ULP apart. ### EXPECT_NEAR {#EXPECT_NEAR} @@ -294,6 +296,11 @@ equal, to within 4 ULPs from each other. Verifies that the difference between *`val1`* and *`val2`* does not exceed the absolute error bound *`abs_error`*. +If *`val`* and *`val2`* are both infinity of the same sign, the difference is +considered to be 0. Otherwise, if either value is infinity, the difference is +considered to be infinity. All non-NaN values (including infinity) are +considered to not exceed an *`abs_error`* of infinity. + ## Exception Assertions {#exceptions} The following assertions verify that a piece of code throws, or does not throw, diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 6662a13c..c08ab419 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -1660,10 +1660,25 @@ std::string GetBoolAssertionFailureMessage( return msg.GetString(); } -// Helper function for implementing ASSERT_NEAR. +// Helper function for implementing ASSERT_NEAR. Treats infinity as a specific +// value, such that comparing infinity to infinity is equal, the distance +// between -infinity and +infinity is infinity, and infinity <= infinity is +// true. AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error) { + // We want to return success when the two values are infinity and at least + // one of the following is true: + // * The values are the same-signed infinity. + // * The error limit itself is infinity. + // This is done here so that we don't end up with a NaN when calculating the + // difference in values. + if (std::isinf(val1) && std::isinf(val2) && + (std::signbit(val1) == std::signbit(val2) || + (abs_error > 0.0 && std::isinf(abs_error)))) { + return AssertionSuccess(); + } + const double diff = fabs(val1 - val2); if (diff <= abs_error) return AssertionSuccess(); diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 5ded8650..2d48deef 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -2870,6 +2870,8 @@ TEST_F(FloatTest, LargeDiff) { // This ensures that no overflow occurs when comparing numbers whose // absolute value is very large. TEST_F(FloatTest, Infinity) { + EXPECT_FLOAT_EQ(values_.infinity, values_.infinity); + EXPECT_FLOAT_EQ(-values_.infinity, -values_.infinity); EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity); EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity); EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity), @@ -2894,6 +2896,11 @@ TEST_F(FloatTest, NaN) { EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), "v.nan1"); EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), "v.nan2"); EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f, v.nan1, 1.0f), "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f, v.nan1, v.infinity), "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, v.nan1, 1.0f), "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, v.nan1, v.infinity), + "v.nan1"); EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), "v.infinity"); } @@ -2917,11 +2924,28 @@ TEST_F(FloatTest, Commutative) { // Tests EXPECT_NEAR. TEST_F(FloatTest, EXPECT_NEAR) { + static const FloatTest::TestValues& v = this->values_; + EXPECT_NEAR(-1.0f, -1.1f, 0.2f); EXPECT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_NEAR(v.infinity, v.infinity, 0.0f); + EXPECT_NEAR(-v.infinity, -v.infinity, 0.0f); + EXPECT_NEAR(0.0f, 1.0f, v.infinity); + EXPECT_NEAR(v.infinity, -v.infinity, v.infinity); + EXPECT_NEAR(-v.infinity, v.infinity, v.infinity); EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f, 1.5f, 0.25f), // NOLINT "The difference between 1.0f and 1.5f is 0.5, " "which exceeds 0.25f"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, -v.infinity, 0.0f), // NOLINT + "The difference between v.infinity and -v.infinity " + "is inf, which exceeds 0.0f"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(-v.infinity, v.infinity, 0.0f), // NOLINT + "The difference between -v.infinity and v.infinity " + "is inf, which exceeds 0.0f"); + EXPECT_NONFATAL_FAILURE( + EXPECT_NEAR(v.infinity, v.close_to_infinity, v.further_from_infinity), + "The difference between v.infinity and v.close_to_infinity is inf, which " + "exceeds v.further_from_infinity"); } // Tests ASSERT_NEAR. @@ -3028,6 +3052,8 @@ TEST_F(DoubleTest, LargeDiff) { // This ensures that no overflow occurs when comparing numbers whose // absolute value is very large. TEST_F(DoubleTest, Infinity) { + EXPECT_DOUBLE_EQ(values_.infinity, values_.infinity); + EXPECT_DOUBLE_EQ(-values_.infinity, -values_.infinity); EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity); EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity), @@ -3047,6 +3073,12 @@ TEST_F(DoubleTest, NaN) { EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), "v.nan1"); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2"); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, v.nan1, 1.0), "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, v.nan1, v.infinity), "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, v.nan1, 1.0), "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, v.nan1, v.infinity), + "v.nan1"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), "v.infinity"); } @@ -3069,11 +3101,28 @@ TEST_F(DoubleTest, Commutative) { // Tests EXPECT_NEAR. TEST_F(DoubleTest, EXPECT_NEAR) { + static const DoubleTest::TestValues& v = this->values_; + EXPECT_NEAR(-1.0, -1.1, 0.2); EXPECT_NEAR(2.0, 3.0, 1.0); + EXPECT_NEAR(v.infinity, v.infinity, 0.0); + EXPECT_NEAR(-v.infinity, -v.infinity, 0.0); + EXPECT_NEAR(0.0, 1.0, v.infinity); + EXPECT_NEAR(v.infinity, -v.infinity, v.infinity); + EXPECT_NEAR(-v.infinity, v.infinity, v.infinity); EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT "The difference between 1.0 and 1.5 is 0.5, " "which exceeds 0.25"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, -v.infinity, 0.0), + "The difference between v.infinity and -v.infinity " + "is inf, which exceeds 0.0"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(-v.infinity, v.infinity, 0.0), + "The difference between -v.infinity and v.infinity " + "is inf, which exceeds 0.0"); + EXPECT_NONFATAL_FAILURE( + EXPECT_NEAR(v.infinity, v.close_to_infinity, v.further_from_infinity), + "The difference between v.infinity and v.close_to_infinity is inf, which " + "exceeds v.further_from_infinity"); // At this magnitude adjacent doubles are 512.0 apart, so this triggers a // slightly different failure reporting path. EXPECT_NONFATAL_FAILURE(