Index: testing/gmock/test/gmock-matchers_test.cc |
diff --git a/testing/gmock/test/gmock-matchers_test.cc b/testing/gmock/test/gmock-matchers_test.cc |
index 907749d19833528b6010f9180b986f67a4be990c..5557983c732c4a31720b2b954f591f621eec4f5e 100644 |
--- a/testing/gmock/test/gmock-matchers_test.cc |
+++ b/testing/gmock/test/gmock-matchers_test.cc |
@@ -37,6 +37,7 @@ |
#include <string.h> |
#include <functional> |
+#include <iostream> |
#include <list> |
#include <map> |
#include <set> |
@@ -88,6 +89,8 @@ using testing::Matcher; |
using testing::MatcherCast; |
using testing::MatcherInterface; |
using testing::Matches; |
+using testing::ExplainMatchResult; |
+using testing::MatchResultListener; |
using testing::NanSensitiveDoubleEq; |
using testing::NanSensitiveFloatEq; |
using testing::Ne; |
@@ -108,6 +111,7 @@ using testing::Truly; |
using testing::TypedEq; |
using testing::Value; |
using testing::_; |
+using testing::internal::DummyMatchResultListener; |
using testing::internal::FloatingEqMatcher; |
using testing::internal::FormatMatcherDescriptionSyntaxError; |
using testing::internal::GetParamIndex; |
@@ -115,8 +119,10 @@ using testing::internal::Interpolation; |
using testing::internal::Interpolations; |
using testing::internal::JoinAsTuple; |
using testing::internal::SkipPrefix; |
+using testing::internal::StreamMatchResultListener; |
using testing::internal::String; |
using testing::internal::Strings; |
+using testing::internal::StringMatchResultListener; |
using testing::internal::ValidateMatcherDescription; |
using testing::internal::kInvalidInterpolation; |
using testing::internal::kPercentInterpolation; |
@@ -125,32 +131,31 @@ using testing::internal::linked_ptr; |
using testing::internal::scoped_ptr; |
using testing::internal::string; |
-#ifdef GMOCK_HAS_REGEX |
using testing::ContainsRegex; |
using testing::MatchesRegex; |
using testing::internal::RE; |
-#endif // GMOCK_HAS_REGEX |
// For testing ExplainMatchResultTo(). |
class GreaterThanMatcher : public MatcherInterface<int> { |
public: |
explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} |
- virtual bool Matches(int lhs) const { return lhs > rhs_; } |
- |
virtual void DescribeTo(::std::ostream* os) const { |
*os << "is greater than " << rhs_; |
} |
- virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const { |
+ virtual bool MatchAndExplain(int lhs, |
+ MatchResultListener* listener) const { |
const int diff = lhs - rhs_; |
if (diff > 0) { |
- *os << "is " << diff << " more than " << rhs_; |
+ *listener << "which is " << diff << " more than " << rhs_; |
} else if (diff == 0) { |
- *os << "is the same as " << rhs_; |
+ *listener << "which is the same as " << rhs_; |
} else { |
- *os << "is " << -diff << " less than " << rhs_; |
+ *listener << "which is " << -diff << " less than " << rhs_; |
} |
+ |
+ return lhs > rhs_; |
} |
private: |
@@ -185,11 +190,39 @@ string Explain(const MatcherType& m, const Value& x) { |
return ss.str(); |
} |
+TEST(MatchResultListenerTest, StreamingWorks) { |
+ StringMatchResultListener listener; |
+ listener << "hi" << 5; |
+ EXPECT_EQ("hi5", listener.str()); |
+ |
+ // Streaming shouldn't crash when the underlying ostream is NULL. |
+ DummyMatchResultListener dummy; |
+ dummy << "hi" << 5; |
+} |
+ |
+TEST(MatchResultListenerTest, CanAccessUnderlyingStream) { |
+ EXPECT_TRUE(DummyMatchResultListener().stream() == NULL); |
+ EXPECT_TRUE(StreamMatchResultListener(NULL).stream() == NULL); |
+ |
+ EXPECT_EQ(&std::cout, StreamMatchResultListener(&std::cout).stream()); |
+} |
+ |
+TEST(MatchResultListenerTest, IsInterestedWorks) { |
+ EXPECT_TRUE(StringMatchResultListener().IsInterested()); |
+ EXPECT_TRUE(StreamMatchResultListener(&std::cout).IsInterested()); |
+ |
+ EXPECT_FALSE(DummyMatchResultListener().IsInterested()); |
+ EXPECT_FALSE(StreamMatchResultListener(NULL).IsInterested()); |
+} |
+ |
// Makes sure that the MatcherInterface<T> interface doesn't |
// change. |
class EvenMatcherImpl : public MatcherInterface<int> { |
public: |
- virtual bool Matches(int x) const { return x % 2 == 0; } |
+ virtual bool MatchAndExplain(int x, |
+ MatchResultListener* /* listener */) const { |
+ return x % 2 == 0; |
+ } |
virtual void DescribeTo(::std::ostream* os) const { |
*os << "is an even number"; |
@@ -200,10 +233,40 @@ class EvenMatcherImpl : public MatcherInterface<int> { |
// two methods is optional. |
}; |
-TEST(MatcherInterfaceTest, CanBeImplemented) { |
+// Makes sure that the MatcherInterface API doesn't change. |
+TEST(MatcherInterfaceTest, CanBeImplementedUsingPublishedAPI) { |
EvenMatcherImpl m; |
} |
+// Tests implementing a monomorphic matcher using MatchAndExplain(). |
+ |
+class NewEvenMatcherImpl : public MatcherInterface<int> { |
+ public: |
+ virtual bool MatchAndExplain(int x, MatchResultListener* listener) const { |
+ const bool match = x % 2 == 0; |
+ // Verifies that we can stream to a listener directly. |
+ *listener << "value % " << 2; |
+ if (listener->stream() != NULL) { |
+ // Verifies that we can stream to a listener's underlying stream |
+ // too. |
+ *listener->stream() << " == " << (x % 2); |
+ } |
+ return match; |
+ } |
+ |
+ virtual void DescribeTo(::std::ostream* os) const { |
+ *os << "is an even number"; |
+ } |
+}; |
+ |
+TEST(MatcherInterfaceTest, CanBeImplementedUsingNewAPI) { |
+ Matcher<int> m = MakeMatcher(new NewEvenMatcherImpl); |
+ EXPECT_TRUE(m.Matches(2)); |
+ EXPECT_FALSE(m.Matches(3)); |
+ EXPECT_EQ("value % 2 == 0", Explain(m, 2)); |
+ EXPECT_EQ("value % 2 == 1", Explain(m, 3)); |
+} |
+ |
// Tests default-constructing a matcher. |
TEST(MatcherTest, CanBeDefaultConstructed) { |
Matcher<double> m; |
@@ -252,6 +315,18 @@ TEST(MatcherTest, CanDescribeItself) { |
Describe(Matcher<int>(new EvenMatcherImpl))); |
} |
+// Tests Matcher<T>::MatchAndExplain(). |
+TEST(MatcherTest, MatchAndExplain) { |
+ Matcher<int> m = GreaterThan(0); |
+ StringMatchResultListener listener1; |
+ EXPECT_TRUE(m.MatchAndExplain(42, &listener1)); |
+ EXPECT_EQ("which is 42 more than 0", listener1.str()); |
+ |
+ StringMatchResultListener listener2; |
+ EXPECT_FALSE(m.MatchAndExplain(-9, &listener2)); |
+ EXPECT_EQ("which is 9 less than 0", listener2.str()); |
+} |
+ |
// Tests that a C-string literal can be implicitly converted to a |
// Matcher<string> or Matcher<const string&>. |
TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { |
@@ -284,13 +359,14 @@ TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) { |
Matcher<int> m = MakeMatcher(dummy_impl); |
} |
-// Tests that MakePolymorphicMatcher() constructs a polymorphic |
-// matcher from its implementation. |
+// Tests that MakePolymorphicMatcher() can construct a polymorphic |
+// matcher from its implementation using the old API. |
const int bar = 1; |
class ReferencesBarOrIsZeroImpl { |
public: |
template <typename T> |
- bool Matches(const T& x) const { |
+ bool MatchAndExplain(const T& x, |
+ MatchResultListener* /* listener */) const { |
const void* p = &x; |
return p == &bar || x == 0; |
} |
@@ -308,7 +384,7 @@ PolymorphicMatcher<ReferencesBarOrIsZeroImpl> ReferencesBarOrIsZero() { |
return MakePolymorphicMatcher(ReferencesBarOrIsZeroImpl()); |
} |
-TEST(MakePolymorphicMatcherTest, ConstructsMatcherFromImpl) { |
+TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingOldAPI) { |
// Using a polymorphic matcher to match a reference type. |
Matcher<const int&> m1 = ReferencesBarOrIsZero(); |
EXPECT_TRUE(m1.Matches(0)); |
@@ -324,6 +400,57 @@ TEST(MakePolymorphicMatcherTest, ConstructsMatcherFromImpl) { |
EXPECT_EQ("bar or zero", Describe(m2)); |
} |
+// Tests implementing a polymorphic matcher using MatchAndExplain(). |
+ |
+class PolymorphicIsEvenImpl { |
+ public: |
+ void DescribeTo(::std::ostream* os) const { *os << "is even"; } |
+ |
+ void DescribeNegationTo(::std::ostream* os) const { |
+ *os << "is odd"; |
+ } |
+ |
+ template <typename T> |
+ bool MatchAndExplain(const T& x, MatchResultListener* listener) const { |
+ // Verifies that we can stream to the listener directly. |
+ *listener << "% " << 2; |
+ if (listener->stream() != NULL) { |
+ // Verifies that we can stream to the listener's underlying stream |
+ // too. |
+ *listener->stream() << " == " << (x % 2); |
+ } |
+ return (x % 2) == 0; |
+ } |
+}; |
+ |
+PolymorphicMatcher<PolymorphicIsEvenImpl> PolymorphicIsEven() { |
+ return MakePolymorphicMatcher(PolymorphicIsEvenImpl()); |
+} |
+ |
+TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingNewAPI) { |
+ // Using PolymorphicIsEven() as a Matcher<int>. |
+ const Matcher<int> m1 = PolymorphicIsEven(); |
+ EXPECT_TRUE(m1.Matches(42)); |
+ EXPECT_FALSE(m1.Matches(43)); |
+ EXPECT_EQ("is even", Describe(m1)); |
+ |
+ const Matcher<int> not_m1 = Not(m1); |
+ EXPECT_EQ("is odd", Describe(not_m1)); |
+ |
+ EXPECT_EQ("% 2 == 0", Explain(m1, 42)); |
+ |
+ // Using PolymorphicIsEven() as a Matcher<char>. |
+ const Matcher<char> m2 = PolymorphicIsEven(); |
+ EXPECT_TRUE(m2.Matches('\x42')); |
+ EXPECT_FALSE(m2.Matches('\x43')); |
+ EXPECT_EQ("is even", Describe(m2)); |
+ |
+ const Matcher<char> not_m2 = Not(m2); |
+ EXPECT_EQ("is odd", Describe(not_m2)); |
+ |
+ EXPECT_EQ("% 2 == 0", Explain(m2, '\x42')); |
+} |
+ |
// Tests that MatcherCast<T>(m) works when m is a polymorphic matcher. |
TEST(MatcherCastTest, FromPolymorphicMatcher) { |
Matcher<int> m = MatcherCast<int>(Eq(5)); |
@@ -1050,21 +1177,41 @@ TEST(PairTest, CanDescribeSelf) { |
} |
TEST(PairTest, CanExplainMatchResultTo) { |
- const Matcher<std::pair<int, int> > m0 = Pair(0, 0); |
- EXPECT_EQ("", Explain(m0, std::make_pair(25, 42))); |
- |
- const Matcher<std::pair<int, int> > m1 = Pair(GreaterThan(0), 0); |
- EXPECT_EQ("the first field is 25 more than 0", |
- Explain(m1, std::make_pair(25, 42))); |
- |
- const Matcher<std::pair<int, int> > m2 = Pair(0, GreaterThan(0)); |
- EXPECT_EQ("the second field is 42 more than 0", |
- Explain(m2, std::make_pair(25, 42))); |
- |
- const Matcher<std::pair<int, int> > m3 = Pair(GreaterThan(0), GreaterThan(0)); |
- EXPECT_EQ("the first field is 25 more than 0" |
- ", and the second field is 42 more than 0", |
- Explain(m3, std::make_pair(25, 42))); |
+ // If neither field matches, Pair() should explain about the first |
+ // field. |
+ const Matcher<std::pair<int, int> > m = Pair(GreaterThan(0), GreaterThan(0)); |
+ EXPECT_EQ("whose first field does not match, which is 1 less than 0", |
+ Explain(m, std::make_pair(-1, -2))); |
+ |
+ // If the first field matches but the second doesn't, Pair() should |
+ // explain about the second field. |
+ EXPECT_EQ("whose second field does not match, which is 2 less than 0", |
+ Explain(m, std::make_pair(1, -2))); |
+ |
+ // If the first field doesn't match but the second does, Pair() |
+ // should explain about the first field. |
+ EXPECT_EQ("whose first field does not match, which is 1 less than 0", |
+ Explain(m, std::make_pair(-1, 2))); |
+ |
+ // If both fields match, Pair() should explain about them both. |
+ EXPECT_EQ("whose both fields match, where the first field is a value " |
+ "which is 1 more than 0, and the second field is a value " |
+ "which is 2 more than 0", |
+ Explain(m, std::make_pair(1, 2))); |
+ |
+ // If only the first match has an explanation, only this explanation should |
+ // be printed. |
+ const Matcher<std::pair<int, int> > explain_first = Pair(GreaterThan(0), 0); |
+ EXPECT_EQ("whose both fields match, where the first field is a value " |
+ "which is 1 more than 0", |
+ Explain(explain_first, std::make_pair(1, 0))); |
+ |
+ // If only the second match has an explanation, only this explanation should |
+ // be printed. |
+ const Matcher<std::pair<int, int> > explain_second = Pair(0, GreaterThan(0)); |
+ EXPECT_EQ("whose both fields match, where the second field is a value " |
+ "which is 1 more than 0", |
+ Explain(explain_second, std::make_pair(0, 1))); |
} |
TEST(PairTest, MatchesCorrectly) { |
@@ -1150,8 +1297,6 @@ TEST(EndsWithTest, CanDescribeSelf) { |
EXPECT_EQ("ends with \"Hi\"", Describe(m)); |
} |
-#ifdef GMOCK_HAS_REGEX |
- |
// Tests MatchesRegex(). |
TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) { |
@@ -1170,8 +1315,8 @@ TEST(MatchesRegexTest, CanDescribeSelf) { |
Matcher<const std::string> m1 = MatchesRegex(string("Hi.*")); |
EXPECT_EQ("matches regular expression \"Hi.*\"", Describe(m1)); |
- Matcher<const char*> m2 = MatchesRegex(new RE("[a-z].*")); |
- EXPECT_EQ("matches regular expression \"[a-z].*\"", Describe(m2)); |
+ Matcher<const char*> m2 = MatchesRegex(new RE("a.*")); |
+ EXPECT_EQ("matches regular expression \"a.*\"", Describe(m2)); |
} |
// Tests ContainsRegex(). |
@@ -1192,10 +1337,9 @@ TEST(ContainsRegexTest, CanDescribeSelf) { |
Matcher<const std::string> m1 = ContainsRegex("Hi.*"); |
EXPECT_EQ("contains regular expression \"Hi.*\"", Describe(m1)); |
- Matcher<const char*> m2 = ContainsRegex(new RE("[a-z].*")); |
- EXPECT_EQ("contains regular expression \"[a-z].*\"", Describe(m2)); |
+ Matcher<const char*> m2 = ContainsRegex(new RE("a.*")); |
+ EXPECT_EQ("contains regular expression \"a.*\"", Describe(m2)); |
} |
-#endif // GMOCK_HAS_REGEX |
// Tests for wide strings. |
#if GTEST_HAS_STD_WSTRING |
@@ -1949,6 +2093,36 @@ TEST(ValueTest, WorksWithMonomorphicMatcher) { |
EXPECT_FALSE(Value(1, ref_n)); |
} |
+TEST(ExplainMatchResultTest, WorksWithPolymorphicMatcher) { |
+ StringMatchResultListener listener1; |
+ EXPECT_TRUE(ExplainMatchResult(PolymorphicIsEven(), 42, &listener1)); |
+ EXPECT_EQ("% 2 == 0", listener1.str()); |
+ |
+ StringMatchResultListener listener2; |
+ EXPECT_FALSE(ExplainMatchResult(Ge(42), 1.5, &listener2)); |
+ EXPECT_EQ("", listener2.str()); |
+} |
+ |
+TEST(ExplainMatchResultTest, WorksWithMonomorphicMatcher) { |
+ const Matcher<int> is_even = PolymorphicIsEven(); |
+ StringMatchResultListener listener1; |
+ EXPECT_TRUE(ExplainMatchResult(is_even, 42, &listener1)); |
+ EXPECT_EQ("% 2 == 0", listener1.str()); |
+ |
+ const Matcher<const double&> is_zero = Eq(0); |
+ StringMatchResultListener listener2; |
+ EXPECT_FALSE(ExplainMatchResult(is_zero, 1.5, &listener2)); |
+ EXPECT_EQ("", listener2.str()); |
+} |
+ |
+MATCHER_P(Really, inner_matcher, "") { |
+ return ExplainMatchResult(inner_matcher, arg, result_listener); |
+} |
+ |
+TEST(ExplainMatchResultTest, WorksInsideMATCHER) { |
+ EXPECT_THAT(0, Really(Eq(0))); |
+} |
+ |
TEST(AllArgsTest, WorksForTuple) { |
EXPECT_THAT(make_tuple(1, 2L), AllArgs(Lt())); |
EXPECT_THAT(make_tuple(2L, 1), Not(AllArgs(Lt()))); |
@@ -2041,8 +2215,8 @@ TEST(MatcherAssertionTest, WorksForByRefArguments) { |
// ASSERT_THAT("hello", starts_with_he) fails to compile with Nokia's |
// Symbian compiler: it tries to compile |
// template<T, U> class MatcherCastImpl { ... |
-// virtual bool Matches(T x) const { |
-// return source_matcher_.Matches(static_cast<U>(x)); |
+// virtual bool MatchAndExplain(T x, ...) const { |
+// return source_matcher_.MatchAndExplain(static_cast<U>(x), ...); |
// with U == string and T == const char* |
// With ASSERT_THAT("hello"...) changed to ASSERT_THAT(string("hello") ... ) |
// the compiler silently crashes with no output. |
@@ -2385,7 +2559,14 @@ TEST(PointeeTest, CanExplainMatchResult) { |
const Matcher<int*> m2 = Pointee(GreaterThan(1)); |
int n = 3; |
- EXPECT_EQ("points to a value that is 2 more than 1", Explain(m2, &n)); |
+ EXPECT_EQ("which points to 3, which is 2 more than 1", |
+ Explain(m2, &n)); |
+} |
+ |
+TEST(PointeeTest, AlwaysExplainsPointee) { |
+ const Matcher<int*> m = Pointee(0); |
+ int n = 42; |
+ EXPECT_EQ("which points to 42", Explain(m, &n)); |
} |
// An uncopyable class. |
@@ -2512,8 +2693,9 @@ TEST(FieldTest, WorksForCompatibleMatcherType) { |
TEST(FieldTest, CanDescribeSelf) { |
Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); |
- EXPECT_EQ("the given field is greater than or equal to 0", Describe(m)); |
- EXPECT_EQ("the given field is not greater than or equal to 0", |
+ EXPECT_EQ("is an object whose given field is greater than or equal to 0", |
+ Describe(m)); |
+ EXPECT_EQ("is an object whose given field is not greater than or equal to 0", |
DescribeNegation(m)); |
} |
@@ -2523,10 +2705,10 @@ TEST(FieldTest, CanExplainMatchResult) { |
AStruct a; |
a.x = 1; |
- EXPECT_EQ("", Explain(m, a)); |
+ EXPECT_EQ("whose given field is 1", Explain(m, a)); |
m = Field(&AStruct::x, GreaterThan(0)); |
- EXPECT_EQ("the given field is 1 more than 0", Explain(m, a)); |
+ EXPECT_EQ("whose given field is 1, which is 1 more than 0", Explain(m, a)); |
} |
// Tests that Field() works when the argument is a pointer to const. |
@@ -2549,6 +2731,16 @@ TEST(FieldForPointerTest, WorksForPointerToNonConst) { |
EXPECT_FALSE(m.Matches(&a)); |
} |
+// Tests that Field() works when the argument is a reference to a const pointer. |
+TEST(FieldForPointerTest, WorksForReferenceToConstPointer) { |
+ Matcher<AStruct* const&> m = Field(&AStruct::x, Ge(0)); |
+ |
+ AStruct a; |
+ EXPECT_TRUE(m.Matches(&a)); |
+ a.x = -1; |
+ EXPECT_FALSE(m.Matches(&a)); |
+} |
+ |
// Tests that Field() does not match the NULL pointer. |
TEST(FieldForPointerTest, DoesNotMatchNull) { |
Matcher<const AStruct*> m = Field(&AStruct::x, _); |
@@ -2572,8 +2764,9 @@ TEST(FieldForPointerTest, WorksForArgumentOfSubType) { |
TEST(FieldForPointerTest, CanDescribeSelf) { |
Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); |
- EXPECT_EQ("the given field is greater than or equal to 0", Describe(m)); |
- EXPECT_EQ("the given field is not greater than or equal to 0", |
+ EXPECT_EQ("is an object whose given field is greater than or equal to 0", |
+ Describe(m)); |
+ EXPECT_EQ("is an object whose given field is not greater than or equal to 0", |
DescribeNegation(m)); |
} |
@@ -2584,10 +2777,11 @@ TEST(FieldForPointerTest, CanExplainMatchResult) { |
AStruct a; |
a.x = 1; |
EXPECT_EQ("", Explain(m, static_cast<const AStruct*>(NULL))); |
- EXPECT_EQ("", Explain(m, &a)); |
+ EXPECT_EQ("which points to an object whose given field is 1", Explain(m, &a)); |
m = Field(&AStruct::x, GreaterThan(0)); |
- EXPECT_EQ("the given field is 1 more than 0", Explain(m, &a)); |
+ EXPECT_EQ("which points to an object whose given field is 1, " |
+ "which is 1 more than 0", Explain(m, &a)); |
} |
// A user-defined class for testing Property(). |
@@ -2706,9 +2900,10 @@ TEST(PropertyTest, WorksForCompatibleMatcherType) { |
TEST(PropertyTest, CanDescribeSelf) { |
Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); |
- EXPECT_EQ("the given property is greater than or equal to 0", Describe(m)); |
- EXPECT_EQ("the given property is not greater than or equal to 0", |
- DescribeNegation(m)); |
+ EXPECT_EQ("is an object whose given property is greater than or equal to 0", |
+ Describe(m)); |
+ EXPECT_EQ("is an object whose given property " |
+ "is not greater than or equal to 0", DescribeNegation(m)); |
} |
// Tests that Property() can explain the match result. |
@@ -2717,10 +2912,10 @@ TEST(PropertyTest, CanExplainMatchResult) { |
AClass a; |
a.set_n(1); |
- EXPECT_EQ("", Explain(m, a)); |
+ EXPECT_EQ("whose given property is 1", Explain(m, a)); |
m = Property(&AClass::n, GreaterThan(0)); |
- EXPECT_EQ("the given property is 1 more than 0", Explain(m, a)); |
+ EXPECT_EQ("whose given property is 1, which is 1 more than 0", Explain(m, a)); |
} |
// Tests that Property() works when the argument is a pointer to const. |
@@ -2747,6 +2942,19 @@ TEST(PropertyForPointerTest, WorksForPointerToNonConst) { |
EXPECT_FALSE(m.Matches(&a)); |
} |
+// Tests that Property() works when the argument is a reference to a |
+// const pointer. |
+TEST(PropertyForPointerTest, WorksForReferenceToConstPointer) { |
+ Matcher<AClass* const&> m = Property(&AClass::s, StartsWith("hi")); |
+ |
+ AClass a; |
+ a.set_s("hill"); |
+ EXPECT_TRUE(m.Matches(&a)); |
+ |
+ a.set_s("hole"); |
+ EXPECT_FALSE(m.Matches(&a)); |
+} |
+ |
// Tests that Property() does not match the NULL pointer. |
TEST(PropertyForPointerTest, WorksForReferenceToNonConstProperty) { |
Matcher<const AClass*> m = Property(&AClass::x, _); |
@@ -2772,9 +2980,10 @@ TEST(PropertyForPointerTest, WorksForArgumentOfSubType) { |
TEST(PropertyForPointerTest, CanDescribeSelf) { |
Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); |
- EXPECT_EQ("the given property is greater than or equal to 0", Describe(m)); |
- EXPECT_EQ("the given property is not greater than or equal to 0", |
- DescribeNegation(m)); |
+ EXPECT_EQ("is an object whose given property is greater than or equal to 0", |
+ Describe(m)); |
+ EXPECT_EQ("is an object whose given property " |
+ "is not greater than or equal to 0", DescribeNegation(m)); |
} |
// Tests that Property() can explain the result of matching a pointer. |
@@ -2784,10 +2993,12 @@ TEST(PropertyForPointerTest, CanExplainMatchResult) { |
AClass a; |
a.set_n(1); |
EXPECT_EQ("", Explain(m, static_cast<const AClass*>(NULL))); |
- EXPECT_EQ("", Explain(m, &a)); |
+ EXPECT_EQ("which points to an object whose given property is 1", |
+ Explain(m, &a)); |
m = Property(&AClass::n, GreaterThan(0)); |
- EXPECT_EQ("the given property is 1 more than 0", Explain(m, &a)); |
+ EXPECT_EQ("which points to an object whose given property is 1, " |
+ "which is 1 more than 0", Explain(m, &a)); |
} |
// Tests ResultOf. |
@@ -2807,10 +3018,10 @@ TEST(ResultOfTest, WorksForFunctionPointers) { |
TEST(ResultOfTest, CanDescribeItself) { |
Matcher<int> matcher = ResultOf(&IntToStringFunction, StrEq("foo")); |
- EXPECT_EQ("result of the given callable is equal to \"foo\"", |
- Describe(matcher)); |
- EXPECT_EQ("result of the given callable is not equal to \"foo\"", |
- DescribeNegation(matcher)); |
+ EXPECT_EQ("is mapped by the given callable to a value that " |
+ "is equal to \"foo\"", Describe(matcher)); |
+ EXPECT_EQ("is mapped by the given callable to a value that " |
+ "is not equal to \"foo\"", DescribeNegation(matcher)); |
} |
// Tests that ResultOf() can explain the match result. |
@@ -2818,11 +3029,12 @@ int IntFunction(int input) { return input == 42 ? 80 : 90; } |
TEST(ResultOfTest, CanExplainMatchResult) { |
Matcher<int> matcher = ResultOf(&IntFunction, Ge(85)); |
- EXPECT_EQ("", Explain(matcher, 36)); |
+ EXPECT_EQ("which is mapped by the given callable to 90", |
+ Explain(matcher, 36)); |
matcher = ResultOf(&IntFunction, GreaterThan(85)); |
- EXPECT_EQ("result of the given callable is 5 more than 85", |
- Explain(matcher, 36)); |
+ EXPECT_EQ("which is mapped by the given callable to 90, " |
+ "which is 5 more than 85", Explain(matcher, 36)); |
} |
// Tests that ResultOf(f, ...) compiles and works as expected when f(x) |
@@ -2958,8 +3170,11 @@ class DivisibleByImpl { |
public: |
explicit DivisibleByImpl(int a_divider) : divider_(a_divider) {} |
+ // For testing using ExplainMatchResultTo() with polymorphic matchers. |
template <typename T> |
- bool Matches(const T& n) const { |
+ bool MatchAndExplain(const T& n, MatchResultListener* listener) const { |
+ *listener << "is " << (n % divider_) << " modulo " |
+ << divider_; |
return (n % divider_) == 0; |
} |
@@ -2978,14 +3193,6 @@ class DivisibleByImpl { |
int divider_; |
}; |
-// For testing using ExplainMatchResultTo() with polymorphic matchers. |
-template <typename T> |
-void ExplainMatchResultTo(const DivisibleByImpl& impl, const T& n, |
- ::std::ostream* os) { |
- *os << "is " << (n % impl.divider()) << " modulo " |
- << impl.divider(); |
-} |
- |
PolymorphicMatcher<DivisibleByImpl> DivisibleBy(int n) { |
return MakePolymorphicMatcher(DivisibleByImpl(n)); |
} |
@@ -3025,7 +3232,7 @@ TEST(ExplainMatchResultTest, AllOf_True_True_2) { |
TEST(ExplainmatcherResultTest, MonomorphicMatcher) { |
const Matcher<int> m = GreaterThan(5); |
- EXPECT_EQ("is 1 more than 5", Explain(m, 6)); |
+ EXPECT_EQ("which is 1 more than 5", Explain(m, 6)); |
} |
// The following two tests verify that values without a public copy |
@@ -3335,6 +3542,16 @@ TEST(ValidateMatcherDescriptionTest, |
ElementsAre()); |
} |
+// The MATCHER*() macros trigger warning C4100 (unreferenced formal |
+// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in |
+// the macro definition, as the warnings are generated when the macro |
+// is expanded and macro expansion cannot contain #pragma. Therefore |
+// we suppress them here. |
+#ifdef _MSC_VER |
+#pragma warning(push) |
+#pragma warning(disable:4100) |
+#endif |
+ |
// We use MATCHER_P3() to define a matcher for testing |
// ValidateMatcherDescription(); otherwise we'll end up with much |
// plumbing code. This is not circular as |
@@ -3345,6 +3562,10 @@ MATCHER_P3(EqInterpolation, start, end, index, "equals Interpolation%(*)s") { |
arg.param_index == index; |
} |
+#ifdef _MSC_VER |
+#pragma warning(pop) |
+#endif |
+ |
TEST(ValidateMatcherDescriptionTest, AcceptsPercentInterpolation) { |
const char* params[] = { "foo", NULL }; |
const char* const desc = "one %%"; |