Googletest export
Rolling forward IsNan() matcher with fixes in test for -Wconversion issues. Use std::nanf and std::nanl where appropriate. PiperOrigin-RevId: 275523003
This commit is contained in:
parent
f966ed1581
commit
011c4e23d5
|
@ -287,6 +287,7 @@ is not changed afterwards, or the meaning of your matcher will be changed.
|
||||||
| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. |
|
| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. |
|
||||||
| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. |
|
| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. |
|
||||||
| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. |
|
| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. |
|
||||||
|
| `IsNan()` | `argument` is any floating-point type with a NaN value. |
|
||||||
<!-- mdformat on -->
|
<!-- mdformat on -->
|
||||||
|
|
||||||
The above matchers use ULP-based comparison (the same as used in googletest).
|
The above matchers use ULP-based comparison (the same as used in googletest).
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -54,6 +54,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
@ -1349,6 +1350,22 @@ MakePredicateFormatterFromMatcher(M matcher) {
|
||||||
return PredicateFormatterFromMatcher<M>(std::move(matcher));
|
return PredicateFormatterFromMatcher<M>(std::move(matcher));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements the polymorphic IsNan() matcher, which matches any floating type
|
||||||
|
// value that is Nan.
|
||||||
|
class IsNanMatcher {
|
||||||
|
public:
|
||||||
|
template <typename FloatType>
|
||||||
|
bool MatchAndExplain(const FloatType& f,
|
||||||
|
MatchResultListener* /* listener */) const {
|
||||||
|
return (::std::isnan)(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeTo(::std::ostream* os) const { *os << "is NaN"; }
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
*os << "isn't NaN";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Implements the polymorphic floating point equality matcher, which matches
|
// Implements the polymorphic floating point equality matcher, which matches
|
||||||
// two float values using ULP-based approximation or, optionally, a
|
// two float values using ULP-based approximation or, optionally, a
|
||||||
// user-specified epsilon. The template is meant to be instantiated with
|
// user-specified epsilon. The template is meant to be instantiated with
|
||||||
|
@ -1409,7 +1426,7 @@ class FloatingEqMatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
const FloatType diff = value - expected_;
|
const FloatType diff = value - expected_;
|
||||||
if (fabs(diff) <= max_abs_error_) {
|
if (::std::fabs(diff) <= max_abs_error_) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3626,6 +3643,11 @@ inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT
|
||||||
return internal::RefMatcher<T&>(x);
|
return internal::RefMatcher<T&>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches any NaN floating point.
|
||||||
|
inline PolymorphicMatcher<internal::IsNanMatcher> IsNan() {
|
||||||
|
return MakePolymorphicMatcher(internal::IsNanMatcher());
|
||||||
|
}
|
||||||
|
|
||||||
// Creates a matcher that matches any double argument approximately
|
// Creates a matcher that matches any double argument approximately
|
||||||
// equal to rhs, where two NANs are considered unequal.
|
// equal to rhs, where two NANs are considered unequal.
|
||||||
inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
|
inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
|
||||||
|
|
|
@ -2054,6 +2054,114 @@ TEST(PairMatchBaseTest, WorksWithMoveOnly) {
|
||||||
EXPECT_TRUE(matcher.Matches(pointers));
|
EXPECT_TRUE(matcher.Matches(pointers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that IsNan() matches a NaN, with float.
|
||||||
|
TEST(IsNan, FloatMatchesNan) {
|
||||||
|
float quiet_nan = std::numeric_limits<float>::quiet_NaN();
|
||||||
|
float other_nan = std::nanf("1");
|
||||||
|
float real_value = 1.0f;
|
||||||
|
|
||||||
|
Matcher<float> m = IsNan();
|
||||||
|
EXPECT_TRUE(m.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m.Matches(real_value));
|
||||||
|
|
||||||
|
Matcher<float&> m_ref = IsNan();
|
||||||
|
EXPECT_TRUE(m_ref.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m_ref.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m_ref.Matches(real_value));
|
||||||
|
|
||||||
|
Matcher<const float&> m_cref = IsNan();
|
||||||
|
EXPECT_TRUE(m_cref.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m_cref.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m_cref.Matches(real_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that IsNan() matches a NaN, with double.
|
||||||
|
TEST(IsNan, DoubleMatchesNan) {
|
||||||
|
double quiet_nan = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
double other_nan = std::nan("1");
|
||||||
|
double real_value = 1.0;
|
||||||
|
|
||||||
|
Matcher<double> m = IsNan();
|
||||||
|
EXPECT_TRUE(m.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m.Matches(real_value));
|
||||||
|
|
||||||
|
Matcher<double&> m_ref = IsNan();
|
||||||
|
EXPECT_TRUE(m_ref.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m_ref.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m_ref.Matches(real_value));
|
||||||
|
|
||||||
|
Matcher<const double&> m_cref = IsNan();
|
||||||
|
EXPECT_TRUE(m_cref.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m_cref.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m_cref.Matches(real_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that IsNan() matches a NaN, with long double.
|
||||||
|
TEST(IsNan, LongDoubleMatchesNan) {
|
||||||
|
long double quiet_nan = std::numeric_limits<long double>::quiet_NaN();
|
||||||
|
long double other_nan = std::nan("1");
|
||||||
|
long double real_value = 1.0;
|
||||||
|
|
||||||
|
Matcher<long double> m = IsNan();
|
||||||
|
EXPECT_TRUE(m.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m.Matches(real_value));
|
||||||
|
|
||||||
|
Matcher<long double&> m_ref = IsNan();
|
||||||
|
EXPECT_TRUE(m_ref.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m_ref.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m_ref.Matches(real_value));
|
||||||
|
|
||||||
|
Matcher<const long double&> m_cref = IsNan();
|
||||||
|
EXPECT_TRUE(m_cref.Matches(quiet_nan));
|
||||||
|
EXPECT_TRUE(m_cref.Matches(other_nan));
|
||||||
|
EXPECT_FALSE(m_cref.Matches(real_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that IsNan() works with Not.
|
||||||
|
TEST(IsNan, NotMatchesNan) {
|
||||||
|
Matcher<float> mf = Not(IsNan());
|
||||||
|
EXPECT_FALSE(mf.Matches(std::numeric_limits<float>::quiet_NaN()));
|
||||||
|
EXPECT_FALSE(mf.Matches(std::nanf("1")));
|
||||||
|
EXPECT_TRUE(mf.Matches(1.0));
|
||||||
|
|
||||||
|
Matcher<double> md = Not(IsNan());
|
||||||
|
EXPECT_FALSE(md.Matches(std::numeric_limits<double>::quiet_NaN()));
|
||||||
|
EXPECT_FALSE(md.Matches(std::nan("1")));
|
||||||
|
EXPECT_TRUE(md.Matches(1.0));
|
||||||
|
|
||||||
|
Matcher<long double> mld = Not(IsNan());
|
||||||
|
EXPECT_FALSE(mld.Matches(std::numeric_limits<long double>::quiet_NaN()));
|
||||||
|
EXPECT_FALSE(mld.Matches(std::nanl("1")));
|
||||||
|
EXPECT_TRUE(mld.Matches(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that IsNan() can describe itself.
|
||||||
|
TEST(IsNan, CanDescribeSelf) {
|
||||||
|
Matcher<float> mf = IsNan();
|
||||||
|
EXPECT_EQ("is NaN", Describe(mf));
|
||||||
|
|
||||||
|
Matcher<double> md = IsNan();
|
||||||
|
EXPECT_EQ("is NaN", Describe(md));
|
||||||
|
|
||||||
|
Matcher<long double> mld = IsNan();
|
||||||
|
EXPECT_EQ("is NaN", Describe(mld));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that IsNan() can describe itself with Not.
|
||||||
|
TEST(IsNan, CanDescribeSelfWithNot) {
|
||||||
|
Matcher<float> mf = Not(IsNan());
|
||||||
|
EXPECT_EQ("isn't NaN", Describe(mf));
|
||||||
|
|
||||||
|
Matcher<double> md = Not(IsNan());
|
||||||
|
EXPECT_EQ("isn't NaN", Describe(md));
|
||||||
|
|
||||||
|
Matcher<long double> mld = Not(IsNan());
|
||||||
|
EXPECT_EQ("isn't NaN", Describe(mld));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that FloatEq() matches a 2-tuple where
|
// Tests that FloatEq() matches a 2-tuple where
|
||||||
// FloatEq(first field) matches the second field.
|
// FloatEq(first field) matches the second field.
|
||||||
TEST(FloatEq2Test, MatchesEqualArguments) {
|
TEST(FloatEq2Test, MatchesEqualArguments) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user