Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions googletest/include/gtest/gtest.h
Original file line number Diff line number Diff line change
Expand Up @@ -1781,12 +1781,24 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
// Helper function for implementing ASSERT_NEAR.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
const char* expr2,
const char* abs_error_expr,
double val1,
double val2,
double abs_error);
template <class R1, class R2, class T>
AssertionResult FPNearPredFormat(const char* expr1, const char* expr2,
const char* abs_error_expr, const R1& val1,
const R2& val2, const T& abs_error) {
auto diff = val1 > val2 ? val1 - val2 : val2 - val1;
if (diff <= abs_error) {
return AssertionSuccess();
}
return AssertionFailure()
<< std::setprecision(std::numeric_limits<
typename std::decay<R1>::type>::max_digits10 +
2)
<< "The difference between " << expr1 << " and " << expr2 << " is "
<< diff << ", which exceeds " << abs_error_expr << ", where\n"
<< expr1 << " evaluates to " << val1 << ",\n"
<< expr2 << " evaluates to " << val2 << ", and\n"
<< abs_error_expr << " evaluates to " << abs_error << ".";
}

// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// A class that enables one to stream messages to assertion macros
Expand Down Expand Up @@ -2167,11 +2179,11 @@ class TestWithParam : public Test, public WithParamInterface<T> {
val1, val2)

#define EXPECT_NEAR(val1, val2, abs_error)\
EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
EXPECT_PRED_FORMAT3(::testing::internal::FPNearPredFormat, \
val1, val2, abs_error)

#define ASSERT_NEAR(val1, val2, abs_error)\
ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
ASSERT_PRED_FORMAT3(::testing::internal::FPNearPredFormat, \
val1, val2, abs_error)

// These predicate format functions work on floating-point values, and
Expand Down
19 changes: 0 additions & 19 deletions googletest/src/gtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1380,25 +1380,6 @@ std::string GetBoolAssertionFailureMessage(
return msg.GetString();
}

// Helper function for implementing ASSERT_NEAR.
AssertionResult DoubleNearPredFormat(const char* expr1,
const char* expr2,
const char* abs_error_expr,
double val1,
double val2,
double abs_error) {
const double diff = fabs(val1 - val2);
if (diff <= abs_error) return AssertionSuccess();

return AssertionFailure()
<< "The difference between " << expr1 << " and " << expr2
<< " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
<< expr1 << " evaluates to " << val1 << ",\n"
<< expr2 << " evaluates to " << val2 << ", and\n"
<< abs_error_expr << " evaluates to " << abs_error << ".";
}


// Helper template for implementing FloatLE() and DoubleLE().
template <typename RawType>
AssertionResult FloatingPointLE(const char* expr1,
Expand Down
94 changes: 94 additions & 0 deletions googletest/test/gtest_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3103,6 +3103,100 @@ TEST_F(DoubleTest, DoubleLEFails) {
}


TEST(LongDoubleTest, EXPECT_NEAR) {
{
long double a = -1.0;
long double b = -1.1;
EXPECT_NEAR(a, b, 0.2);
}
{
long double a = -1.0;
long double b = -1.5;
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(a, b, 0.25), // NOLINT
"The difference between a and b is 0.5, "
"which exceeds 0.25, where\na evaluates to -1,\nb "
"evaluates to -1.5, and\n0.25 evaluates to 0.25.");
}
}

TEST(LongDoubleTest, ASSERT_NEAR) {
{
long double a = -1.0;
long double b = -1.1;
ASSERT_NEAR(a, b, 0.2);
}
{
EXPECT_FATAL_FAILURE(long double a = -1.0; long double b = -1.5;
ASSERT_NEAR(a, b, 0.25), // NOLINT
"The difference between a and b is 0.5, "
"which exceeds 0.25, where\na evaluates to -1,\nb "
"evaluates to -1.5, and\n0.25 evaluates to 0.25.");
}
}

namespace custom_real_ns {
// a custom floating-point like type which implements the minimal interface
// required to test EXPECT_NEAR on a custom type
class custom_real {
// internally stores as a double to prevent having to implement an actual
// custom real-like type
double value_;

public:
explicit custom_real(double value) : value_(value) {}
friend custom_real operator-(custom_real l, custom_real r) {
return custom_real(l.value_ - r.value_);
}
friend bool operator>(custom_real l, custom_real r) {
return l.value_ > r.value_;
}
friend bool operator<=(custom_real l, custom_real r) {
return l.value_ <= r.value_;
}
friend std::ostream& operator<<(std::ostream& out, custom_real v) {
out << v.value_;
return out;
}
};
} // namespace custom_real_ns

TEST(CustomRealTest, EXPECT_NEAR) {
{
custom_real_ns::custom_real a(-1.0);
custom_real_ns::custom_real b(-1.1);
EXPECT_NEAR(a, b, custom_real_ns::custom_real(0.2));
}
{
custom_real_ns::custom_real a(-1.0);
custom_real_ns::custom_real b(-1.5);
EXPECT_NONFATAL_FAILURE(
EXPECT_NEAR(a, b, custom_real_ns::custom_real(0.25)), // NOLINT
"The difference between a and b is 0.5, "
"which exceeds custom_real_ns::custom_real(0.25), where\na evaluates "
"to -1,\nb "
"evaluates to -1.5, and\ncustom_real_ns::custom_real(0.25) evaluates "
"to 0.25.");
}
}
TEST(CustomRealTest, ASSERT_NEAR) {
{
custom_real_ns::custom_real a(-1.0);
custom_real_ns::custom_real b(-1.1);
ASSERT_NEAR(a, b, custom_real_ns::custom_real(0.2));
}
{
EXPECT_FATAL_FAILURE(
custom_real_ns::custom_real a(-1.0);
custom_real_ns::custom_real b(-1.5);
ASSERT_NEAR(a, b, custom_real_ns::custom_real(0.25)), // NOLINT
"The difference between a and b is 0.5, "
"which exceeds custom_real_ns::custom_real(0.25), where\na evaluates "
"to -1,\nb "
"evaluates to -1.5, and\ncustom_real_ns::custom_real(0.25) evaluates "
"to 0.25.");
}
}

// Verifies that a test or test case whose name starts with DISABLED_ is
// not run.

Expand Down