summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2024-10-14 17:12:38 (GMT)
committerCopybara-Service <copybara-worker@google.com>2024-10-14 17:13:58 (GMT)
commit62df7bdbc10887e094661e07ec2595b7920376fd (patch)
tree461f8d5a86a3501484157c6764195620ff881826
parent71815bbf7de6e10c11821d654a2fae2cf42de0f7 (diff)
downloadgoogletest-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.md11
-rw-r--r--googletest/src/gtest.cc17
-rw-r--r--googletest/test/gtest_unittest.cc49
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(