aboutsummaryrefslogtreecommitdiff
path: root/googlemock/test/gmock-matchers-arithmetic_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'googlemock/test/gmock-matchers-arithmetic_test.cc')
-rw-r--r--googlemock/test/gmock-matchers-arithmetic_test.cc237
1 files changed, 210 insertions, 27 deletions
diff --git a/googlemock/test/gmock-matchers-arithmetic_test.cc b/googlemock/test/gmock-matchers-arithmetic_test.cc
index f176962855ea..b6c35119e29b 100644
--- a/googlemock/test/gmock-matchers-arithmetic_test.cc
+++ b/googlemock/test/gmock-matchers-arithmetic_test.cc
@@ -34,9 +34,12 @@
#include <cmath>
#include <limits>
#include <memory>
+#include <ostream>
#include <string>
+#include "gmock/gmock.h"
#include "test/gmock-matchers_test.h"
+#include "gtest/gtest.h"
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
// possible loss of data and C4100, unreferenced local parameter
@@ -396,6 +399,188 @@ TEST(NanSensitiveDoubleNearTest, CanDescribeSelfWithNaNs) {
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
+// Tests that DistanceFrom() can describe itself properly.
+TEST(DistanceFrom, CanDescribeSelf) {
+ Matcher<double> m = DistanceFrom(1.5, Lt(0.1));
+ EXPECT_EQ(Describe(m), "is < 0.1 away from 1.5");
+
+ m = DistanceFrom(2.5, Gt(0.2));
+ EXPECT_EQ(Describe(m), "is > 0.2 away from 2.5");
+}
+
+// Tests that DistanceFrom() can explain match failure.
+TEST(DistanceFrom, CanExplainMatchFailure) {
+ Matcher<double> m = DistanceFrom(1.5, Lt(0.1));
+ EXPECT_EQ(Explain(m, 2.0), "which is 0.5 away from 1.5");
+}
+
+// Tests that DistanceFrom() matches a double that is within the given range of
+// the given value.
+TEST(DistanceFrom, MatchesDoubleWithinRange) {
+ const Matcher<double> m = DistanceFrom(0.5, Le(0.1));
+ EXPECT_TRUE(m.Matches(0.45));
+ EXPECT_TRUE(m.Matches(0.5));
+ EXPECT_TRUE(m.Matches(0.55));
+ EXPECT_FALSE(m.Matches(0.39));
+ EXPECT_FALSE(m.Matches(0.61));
+}
+
+// Tests that DistanceFrom() matches a double reference that is within the given
+// range of the given value.
+TEST(DistanceFrom, MatchesDoubleRefWithinRange) {
+ const Matcher<const double&> m = DistanceFrom(0.5, Le(0.1));
+ EXPECT_TRUE(m.Matches(0.45));
+ EXPECT_TRUE(m.Matches(0.5));
+ EXPECT_TRUE(m.Matches(0.55));
+ EXPECT_FALSE(m.Matches(0.39));
+ EXPECT_FALSE(m.Matches(0.61));
+}
+
+// Tests that DistanceFrom() can be implicitly converted to a matcher depending
+// on the type of the argument.
+TEST(DistanceFrom, CanBeImplicitlyConvertedToMatcher) {
+ EXPECT_THAT(0.58, DistanceFrom(0.5, Le(0.1)));
+ EXPECT_THAT(0.2, Not(DistanceFrom(0.5, Le(0.1))));
+
+ EXPECT_THAT(0.58f, DistanceFrom(0.5f, Le(0.1f)));
+ EXPECT_THAT(0.7f, Not(DistanceFrom(0.5f, Le(0.1f))));
+}
+
+// Tests that DistanceFrom() can be used on compatible types (i.e. not
+// everything has to be of the same type).
+TEST(DistanceFrom, CanBeUsedOnCompatibleTypes) {
+ EXPECT_THAT(0.58, DistanceFrom(0.5, Le(0.1f)));
+ EXPECT_THAT(0.2, Not(DistanceFrom(0.5, Le(0.1f))));
+
+ EXPECT_THAT(0.58, DistanceFrom(0.5f, Le(0.1)));
+ EXPECT_THAT(0.2, Not(DistanceFrom(0.5f, Le(0.1))));
+
+ EXPECT_THAT(0.58, DistanceFrom(0.5f, Le(0.1f)));
+ EXPECT_THAT(0.2, Not(DistanceFrom(0.5f, Le(0.1f))));
+
+ EXPECT_THAT(0.58f, DistanceFrom(0.5, Le(0.1)));
+ EXPECT_THAT(0.2f, Not(DistanceFrom(0.5, Le(0.1))));
+
+ EXPECT_THAT(0.58f, DistanceFrom(0.5, Le(0.1f)));
+ EXPECT_THAT(0.2f, Not(DistanceFrom(0.5, Le(0.1f))));
+
+ EXPECT_THAT(0.58f, DistanceFrom(0.5f, Le(0.1)));
+ EXPECT_THAT(0.2f, Not(DistanceFrom(0.5f, Le(0.1))));
+}
+
+// A 2-dimensional point. For testing using DistanceFrom() with a custom type
+// that doesn't have a built-in distance function.
+class Point {
+ public:
+ Point(double x, double y) : x_(x), y_(y) {}
+ double x() const { return x_; }
+ double y() const { return y_; }
+
+ private:
+ double x_;
+ double y_;
+};
+
+// Returns the distance between two points.
+double PointDistance(const Point& lhs, const Point& rhs) {
+ return std::sqrt(std::pow(lhs.x() - rhs.x(), 2) +
+ std::pow(lhs.y() - rhs.y(), 2));
+}
+
+// Tests that DistanceFrom() can be used on a type with a custom distance
+// function.
+TEST(DistanceFrom, CanBeUsedOnTypeWithCustomDistanceFunction) {
+ const Matcher<Point> m =
+ DistanceFrom(Point(0.5, 0.5), PointDistance, Le(0.1));
+ EXPECT_THAT(Point(0.45, 0.45), m);
+ EXPECT_THAT(Point(0.2, 0.45), Not(m));
+}
+
+// A wrapper around a double value. For testing using DistanceFrom() with a
+// custom type that has neither a built-in distance function nor a built-in
+// distance comparator.
+class Double {
+ public:
+ explicit Double(double value) : value_(value) {}
+ Double(const Double& other) = default;
+ double value() const { return value_; }
+
+ // Defines how to print a Double value. We don't use the AbslStringify API
+ // because googletest doesn't require absl yet.
+ friend void PrintTo(const Double& value, std::ostream* os) {
+ *os << "Double(" << value.value() << ")";
+ }
+
+ private:
+ double value_;
+};
+
+// Returns the distance between two Double values.
+Double DoubleDistance(Double lhs, Double rhs) {
+ return Double(std::abs(lhs.value() - rhs.value()));
+}
+
+MATCHER_P(DoubleLe, rhs, (negation ? "is > " : "is <= ") + PrintToString(rhs)) {
+ return arg.value() <= rhs.value();
+}
+
+// Tests that DistanceFrom() can describe itself properly for a type with a
+// custom printer.
+TEST(DistanceFrom, CanDescribeWithCustomPrinter) {
+ const Matcher<Double> m =
+ DistanceFrom(Double(0.5), DoubleDistance, DoubleLe(Double(0.1)));
+ EXPECT_EQ(Describe(m), "is <= Double(0.1) away from Double(0.5)");
+ EXPECT_EQ(DescribeNegation(m), "is > Double(0.1) away from Double(0.5)");
+}
+
+// Tests that DistanceFrom() can be used with a custom distance function and
+// comparator.
+TEST(DistanceFrom, CanCustomizeDistanceAndComparator) {
+ const Matcher<Double> m =
+ DistanceFrom(Double(0.5), DoubleDistance, DoubleLe(Double(0.1)));
+ EXPECT_TRUE(m.Matches(Double(0.45)));
+ EXPECT_TRUE(m.Matches(Double(0.5)));
+ EXPECT_FALSE(m.Matches(Double(0.39)));
+ EXPECT_FALSE(m.Matches(Double(0.61)));
+}
+
+// For testing using DistanceFrom() with a type that supports both - and abs.
+class Float {
+ public:
+ explicit Float(float value) : value_(value) {}
+ Float(const Float& other) = default;
+ float value() const { return value_; }
+
+ private:
+ float value_ = 0.0f;
+};
+
+// Returns the difference between two Float values. This must be defined in the
+// same namespace as Float.
+Float operator-(const Float& lhs, const Float& rhs) {
+ return Float(lhs.value() - rhs.value());
+}
+
+// Returns the absolute value of a Float value. This must be defined in the
+// same namespace as Float.
+Float abs(Float value) { return Float(std::abs(value.value())); }
+
+// Returns true if and only if the first Float value is less than the second
+// Float value. This must be defined in the same namespace as Float.
+bool operator<(const Float& lhs, const Float& rhs) {
+ return lhs.value() < rhs.value();
+}
+
+// Tests that DistanceFrom() can be used with a type that supports both - and
+// abs.
+TEST(DistanceFrom, CanBeUsedWithTypeThatSupportsBothMinusAndAbs) {
+ const Matcher<Float> m = DistanceFrom(Float(0.5f), Lt(Float(0.1f)));
+ EXPECT_TRUE(m.Matches(Float(0.45f)));
+ EXPECT_TRUE(m.Matches(Float(0.55f)));
+ EXPECT_FALSE(m.Matches(Float(0.39f)));
+ EXPECT_FALSE(m.Matches(Float(0.61f)));
+}
+
// Tests that Not(m) matches any value that doesn't match m.
TEST(NotTest, NegatesMatcher) {
Matcher<int> m;
@@ -559,10 +744,9 @@ TEST_P(AllOfTestP, ExplainsResult) {
Matcher<int> m;
// Successful match. Both matchers need to explain. The second
- // matcher doesn't give an explanation, so only the first matcher's
- // explanation is printed.
+ // matcher doesn't give an explanation, so the matcher description is used.
m = AllOf(GreaterThan(10), Lt(30));
- EXPECT_EQ("which is 15 more than 10", Explain(m, 25));
+ EXPECT_EQ("which is 15 more than 10, and is < 30", Explain(m, 25));
// Successful match. Both matchers need to explain.
m = AllOf(GreaterThan(10), GreaterThan(20));
@@ -572,8 +756,9 @@ TEST_P(AllOfTestP, ExplainsResult) {
// Successful match. All matchers need to explain. The second
// matcher doesn't given an explanation.
m = AllOf(GreaterThan(10), Lt(30), GreaterThan(20));
- EXPECT_EQ("which is 15 more than 10, and which is 5 more than 20",
- Explain(m, 25));
+ EXPECT_EQ(
+ "which is 15 more than 10, and is < 30, and which is 5 more than 20",
+ Explain(m, 25));
// Successful match. All matchers need to explain.
m = AllOf(GreaterThan(10), GreaterThan(20), GreaterThan(30));
@@ -588,10 +773,10 @@ TEST_P(AllOfTestP, ExplainsResult) {
EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
// Failed match. The second matcher, which failed, needs to
- // explain. Since it doesn't given an explanation, nothing is
+ // explain. Since it doesn't given an explanation, the matcher text is
// printed.
m = AllOf(GreaterThan(10), Lt(30));
- EXPECT_EQ("", Explain(m, 40));
+ EXPECT_EQ("which doesn't match (is < 30)", Explain(m, 40));
// Failed match. The second matcher, which failed, needs to
// explain.
@@ -774,45 +959,43 @@ TEST(AnyOfTest, AnyOfMatcherSafelyCastsMonomorphicMatchers) {
TEST_P(AnyOfTestP, ExplainsResult) {
Matcher<int> m;
- // Failed match. Both matchers need to explain. The second
- // matcher doesn't give an explanation, so only the first matcher's
- // explanation is printed.
+ // Failed match. The second matcher have no explanation (description is used).
m = AnyOf(GreaterThan(10), Lt(0));
- EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
+ EXPECT_EQ("which is 5 less than 10, and isn't < 0", Explain(m, 5));
- // Failed match. Both matchers need to explain.
+ // Failed match. Both matchers have explanations.
m = AnyOf(GreaterThan(10), GreaterThan(20));
EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20",
Explain(m, 5));
- // Failed match. All matchers need to explain. The second
- // matcher doesn't given an explanation.
+ // Failed match. The middle matcher have no explanation.
m = AnyOf(GreaterThan(10), Gt(20), GreaterThan(30));
- EXPECT_EQ("which is 5 less than 10, and which is 25 less than 30",
- Explain(m, 5));
+ EXPECT_EQ(
+ "which is 5 less than 10, and isn't > 20, and which is 25 less than 30",
+ Explain(m, 5));
- // Failed match. All matchers need to explain.
+ // Failed match. All three matchers have explanations.
m = AnyOf(GreaterThan(10), GreaterThan(20), GreaterThan(30));
EXPECT_EQ(
"which is 5 less than 10, and which is 15 less than 20, "
"and which is 25 less than 30",
Explain(m, 5));
- // Successful match. The first matcher, which succeeded, needs to
- // explain.
+ // Successful match. The first macher succeeded and has explanation.
m = AnyOf(GreaterThan(10), GreaterThan(20));
EXPECT_EQ("which is 5 more than 10", Explain(m, 15));
- // Successful match. The second matcher, which succeeded, needs to
- // explain. Since it doesn't given an explanation, nothing is
- // printed.
- m = AnyOf(GreaterThan(10), Lt(30));
- EXPECT_EQ("", Explain(m, 0));
-
- // Successful match. The second matcher, which succeeded, needs to
- // explain.
+ // Successful match. The second matcher succeeded and has explanation.
m = AnyOf(GreaterThan(30), GreaterThan(20));
EXPECT_EQ("which is 5 more than 20", Explain(m, 25));
+
+ // Successful match. The first matcher succeeded and has no explanation.
+ m = AnyOf(Gt(10), Lt(20));
+ EXPECT_EQ("which matches (is > 10)", Explain(m, 15));
+
+ // Successful match. The second matcher succeeded and has no explanation.
+ m = AnyOf(Gt(30), Gt(20));
+ EXPECT_EQ("which matches (is > 20)", Explain(m, 25));
}
// The following predicate function and predicate functor are for