diff options
author | Abseil Team <absl-team@google.com> | 2024-10-14 17:12:38 (GMT) |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-10-14 17:13:58 (GMT) |
commit | 62df7bdbc10887e094661e07ec2595b7920376fd (patch) | |
tree | 461f8d5a86a3501484157c6764195620ff881826 | |
parent | 71815bbf7de6e10c11821d654a2fae2cf42de0f7 (diff) | |
download | googletest-62df7bdbc10887e094661e07ec2595b7920376fd.zip googletest-62df7bdbc10887e094661e07ec2595b7920376fd.tar.gz googletest-62df7bdbc10887e094661e07ec2595b7920376fd.tar.bz2 |
This change adjusts how `ASSERT_NEAR` and `EXPECT_NEAR` treats infinity, such that `ASSERT_NEAR(inf, inf, 0)` passes. This makes the behavior more consistent with `ASSERT_EQ(inf, inf)` which succeeds.
Some examples of asserts that now pass:
```
ASSERT_NEAR(inf, inf, 0)
ASSERT_NEAR(-inf, inf, inf)
ASSERT_NEAR(inf, x, inf) // x is any finite floating point value
```
PiperOrigin-RevId: 685748133
Change-Id: I7b3af377773e8e0031e4c6b86830cbbf76bf20c6
-rw-r--r-- | docs/reference/assertions.md | 11 | ||||
-rw-r--r-- | googletest/src/gtest.cc | 17 | ||||
-rw-r--r-- | googletest/test/gtest_unittest.cc | 49 |
3 files changed, 74 insertions, 3 deletions
diff --git a/docs/reference/assertions.md b/docs/reference/assertions.md index 492ff5e..eeec4a0 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 6662a13..c08ab41 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 5ded865..2d48dee 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( |