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 6d784f16cb97783359b77df080a0d9459ef5c59d..3b151dbd9bf62342bb9ae76ff1bcb42ef1090009 100644 |
--- a/testing/gmock/test/gmock-matchers_test.cc |
+++ b/testing/gmock/test/gmock-matchers_test.cc |
@@ -61,12 +61,19 @@ bool SkipPrefix(const char* prefix, const char** pstr); |
namespace gmock_matchers_test { |
+using std::list; |
using std::make_pair; |
using std::map; |
using std::multimap; |
+using std::multiset; |
+using std::ostream; |
using std::pair; |
+using std::set; |
using std::stringstream; |
+using std::tr1::get; |
using std::tr1::make_tuple; |
+using std::tr1::tuple; |
+using std::vector; |
using testing::A; |
using testing::AllArgs; |
using testing::AllOf; |
@@ -102,6 +109,7 @@ using testing::Not; |
using testing::NotNull; |
using testing::Pair; |
using testing::Pointee; |
+using testing::Pointwise; |
using testing::PolymorphicMatcher; |
using testing::Property; |
using testing::Ref; |
@@ -142,7 +150,7 @@ class GreaterThanMatcher : public MatcherInterface<int> { |
public: |
explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} |
- virtual void DescribeTo(::std::ostream* os) const { |
+ virtual void DescribeTo(ostream* os) const { |
*os << "is > " << rhs_; |
} |
@@ -187,9 +195,9 @@ string DescribeNegation(const Matcher<T>& m) { |
// Returns the reason why x matches, or doesn't match, m. |
template <typename MatcherType, typename Value> |
string Explain(const MatcherType& m, const Value& x) { |
- stringstream ss; |
- m.ExplainMatchResultTo(x, &ss); |
- return ss.str(); |
+ StringMatchResultListener listener; |
+ ExplainMatchResult(m, x, &listener); |
+ return listener.str(); |
} |
TEST(MatchResultListenerTest, StreamingWorks) { |
@@ -226,7 +234,7 @@ class EvenMatcherImpl : public MatcherInterface<int> { |
return x % 2 == 0; |
} |
- virtual void DescribeTo(::std::ostream* os) const { |
+ virtual void DescribeTo(ostream* os) const { |
*os << "is an even number"; |
} |
@@ -256,7 +264,7 @@ class NewEvenMatcherImpl : public MatcherInterface<int> { |
return match; |
} |
- virtual void DescribeTo(::std::ostream* os) const { |
+ virtual void DescribeTo(ostream* os) const { |
*os << "is an even number"; |
} |
}; |
@@ -363,20 +371,20 @@ TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) { |
// Tests that MakePolymorphicMatcher() can construct a polymorphic |
// matcher from its implementation using the old API. |
-const int bar = 1; |
+const int g_bar = 1; |
class ReferencesBarOrIsZeroImpl { |
public: |
template <typename T> |
bool MatchAndExplain(const T& x, |
MatchResultListener* /* listener */) const { |
const void* p = &x; |
- return p == &bar || x == 0; |
+ return p == &g_bar || x == 0; |
} |
- void DescribeTo(::std::ostream* os) const { *os << "bar or zero"; } |
+ void DescribeTo(ostream* os) const { *os << "g_bar or zero"; } |
- void DescribeNegationTo(::std::ostream* os) const { |
- *os << "doesn't reference bar and is not zero"; |
+ void DescribeNegationTo(ostream* os) const { |
+ *os << "doesn't reference g_bar and is not zero"; |
} |
}; |
@@ -391,24 +399,24 @@ TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingOldAPI) { |
Matcher<const int&> m1 = ReferencesBarOrIsZero(); |
EXPECT_TRUE(m1.Matches(0)); |
// Verifies that the identity of a by-reference argument is preserved. |
- EXPECT_TRUE(m1.Matches(bar)); |
+ EXPECT_TRUE(m1.Matches(g_bar)); |
EXPECT_FALSE(m1.Matches(1)); |
- EXPECT_EQ("bar or zero", Describe(m1)); |
+ EXPECT_EQ("g_bar or zero", Describe(m1)); |
// Using a polymorphic matcher to match a value type. |
Matcher<double> m2 = ReferencesBarOrIsZero(); |
EXPECT_TRUE(m2.Matches(0.0)); |
EXPECT_FALSE(m2.Matches(0.1)); |
- EXPECT_EQ("bar or zero", Describe(m2)); |
+ EXPECT_EQ("g_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 DescribeTo(ostream* os) const { *os << "is even"; } |
- void DescribeNegationTo(::std::ostream* os) const { |
+ void DescribeNegationTo(ostream* os) const { |
*os << "is odd"; |
} |
@@ -1148,7 +1156,7 @@ TEST(KeyTest, SafelyCastsInnerMatcher) { |
} |
TEST(KeyTest, InsideContainsUsingMap) { |
- std::map<int, char> container; |
+ map<int, char> container; |
container.insert(make_pair(1, 'a')); |
container.insert(make_pair(2, 'b')); |
container.insert(make_pair(4, 'c')); |
@@ -1157,7 +1165,7 @@ TEST(KeyTest, InsideContainsUsingMap) { |
} |
TEST(KeyTest, InsideContainsUsingMultimap) { |
- std::multimap<int, char> container; |
+ multimap<int, char> container; |
container.insert(make_pair(1, 'a')); |
container.insert(make_pair(2, 'b')); |
container.insert(make_pair(4, 'c')); |
@@ -1266,7 +1274,7 @@ TEST(PairTest, SafelyCastsInnerMatchers) { |
} |
TEST(PairTest, InsideContainsUsingMap) { |
- std::map<int, char> container; |
+ map<int, char> container; |
container.insert(make_pair(1, 'a')); |
container.insert(make_pair(2, 'b')); |
container.insert(make_pair(4, 'c')); |
@@ -1759,7 +1767,7 @@ TEST(Eq2Test, MatchesEqualArguments) { |
// Tests that Eq() describes itself properly. |
TEST(Eq2Test, CanDescribeSelf) { |
Matcher<const Tuple2&> m = Eq(); |
- EXPECT_EQ("are a pair (x, y) where x == y", Describe(m)); |
+ EXPECT_EQ("are an equal pair", Describe(m)); |
} |
// Tests that Ge() matches a 2-tuple where the first field >= the |
@@ -1774,7 +1782,7 @@ TEST(Ge2Test, MatchesGreaterThanOrEqualArguments) { |
// Tests that Ge() describes itself properly. |
TEST(Ge2Test, CanDescribeSelf) { |
Matcher<const Tuple2&> m = Ge(); |
- EXPECT_EQ("are a pair (x, y) where x >= y", Describe(m)); |
+ EXPECT_EQ("are a pair where the first >= the second", Describe(m)); |
} |
// Tests that Gt() matches a 2-tuple where the first field > the |
@@ -1789,7 +1797,7 @@ TEST(Gt2Test, MatchesGreaterThanArguments) { |
// Tests that Gt() describes itself properly. |
TEST(Gt2Test, CanDescribeSelf) { |
Matcher<const Tuple2&> m = Gt(); |
- EXPECT_EQ("are a pair (x, y) where x > y", Describe(m)); |
+ EXPECT_EQ("are a pair where the first > the second", Describe(m)); |
} |
// Tests that Le() matches a 2-tuple where the first field <= the |
@@ -1804,7 +1812,7 @@ TEST(Le2Test, MatchesLessThanOrEqualArguments) { |
// Tests that Le() describes itself properly. |
TEST(Le2Test, CanDescribeSelf) { |
Matcher<const Tuple2&> m = Le(); |
- EXPECT_EQ("are a pair (x, y) where x <= y", Describe(m)); |
+ EXPECT_EQ("are a pair where the first <= the second", Describe(m)); |
} |
// Tests that Lt() matches a 2-tuple where the first field < the |
@@ -1819,7 +1827,7 @@ TEST(Lt2Test, MatchesLessThanArguments) { |
// Tests that Lt() describes itself properly. |
TEST(Lt2Test, CanDescribeSelf) { |
Matcher<const Tuple2&> m = Lt(); |
- EXPECT_EQ("are a pair (x, y) where x < y", Describe(m)); |
+ EXPECT_EQ("are a pair where the first < the second", Describe(m)); |
} |
// Tests that Ne() matches a 2-tuple where the first field != the |
@@ -1834,7 +1842,7 @@ TEST(Ne2Test, MatchesUnequalArguments) { |
// Tests that Ne() describes itself properly. |
TEST(Ne2Test, CanDescribeSelf) { |
Matcher<const Tuple2&> m = Ne(); |
- EXPECT_EQ("are a pair (x, y) where x != y", Describe(m)); |
+ EXPECT_EQ("are an unequal pair", Describe(m)); |
} |
// Tests that Not(m) matches any value that doesn't match m. |
@@ -3336,11 +3344,11 @@ class DivisibleByImpl { |
return (n % divider_) == 0; |
} |
- void DescribeTo(::std::ostream* os) const { |
+ void DescribeTo(ostream* os) const { |
*os << "is divisible by " << divider_; |
} |
- void DescribeNegationTo(::std::ostream* os) const { |
+ void DescribeNegationTo(ostream* os) const { |
*os << "is not divisible by " << divider_; |
} |
@@ -3442,10 +3450,10 @@ template <typename T> |
class ContainerEqTest : public testing::Test {}; |
typedef testing::Types< |
- std::set<int>, |
- std::vector<size_t>, |
- std::multiset<size_t>, |
- std::list<int> > |
+ set<int>, |
+ vector<size_t>, |
+ multiset<size_t>, |
+ list<int> > |
ContainerEqTestTypes; |
TYPED_TEST_CASE(ContainerEqTest, ContainerEqTestTypes); |
@@ -3513,9 +3521,9 @@ TYPED_TEST(ContainerEqTest, DuplicateDifference) { |
TEST(ContainerEqExtraTest, MultipleValuesMissing) { |
static const int vals[] = {1, 1, 2, 3, 5, 8}; |
static const int test_vals[] = {2, 1, 5}; |
- std::vector<int> my_set(vals, vals + 6); |
- std::vector<int> test_set(test_vals, test_vals + 3); |
- const Matcher<std::vector<int> > m = ContainerEq(my_set); |
+ vector<int> my_set(vals, vals + 6); |
+ vector<int> test_set(test_vals, test_vals + 3); |
+ const Matcher<vector<int> > m = ContainerEq(my_set); |
EXPECT_FALSE(m.Matches(test_set)); |
EXPECT_EQ("which doesn't have these expected elements: 3, 8", |
Explain(m, test_set)); |
@@ -3526,9 +3534,9 @@ TEST(ContainerEqExtraTest, MultipleValuesMissing) { |
TEST(ContainerEqExtraTest, MultipleValuesAdded) { |
static const int vals[] = {1, 1, 2, 3, 5, 8}; |
static const int test_vals[] = {1, 2, 92, 3, 5, 8, 46}; |
- std::list<size_t> my_set(vals, vals + 6); |
- std::list<size_t> test_set(test_vals, test_vals + 7); |
- const Matcher<const std::list<size_t>&> m = ContainerEq(my_set); |
+ list<size_t> my_set(vals, vals + 6); |
+ list<size_t> test_set(test_vals, test_vals + 7); |
+ const Matcher<const list<size_t>&> m = ContainerEq(my_set); |
EXPECT_FALSE(m.Matches(test_set)); |
EXPECT_EQ("which has these unexpected elements: 92, 46", |
Explain(m, test_set)); |
@@ -3538,9 +3546,9 @@ TEST(ContainerEqExtraTest, MultipleValuesAdded) { |
TEST(ContainerEqExtraTest, MultipleValuesAddedAndRemoved) { |
static const int vals[] = {1, 1, 2, 3, 5, 8}; |
static const int test_vals[] = {1, 2, 3, 92, 46}; |
- std::list<size_t> my_set(vals, vals + 6); |
- std::list<size_t> test_set(test_vals, test_vals + 5); |
- const Matcher<const std::list<size_t> > m = ContainerEq(my_set); |
+ list<size_t> my_set(vals, vals + 6); |
+ list<size_t> test_set(test_vals, test_vals + 5); |
+ const Matcher<const list<size_t> > m = ContainerEq(my_set); |
EXPECT_FALSE(m.Matches(test_set)); |
EXPECT_EQ("which has these unexpected elements: 92, 46,\n" |
"and doesn't have these expected elements: 5, 8", |
@@ -3552,9 +3560,9 @@ TEST(ContainerEqExtraTest, MultipleValuesAddedAndRemoved) { |
TEST(ContainerEqExtraTest, MultiSetOfIntDuplicateDifference) { |
static const int vals[] = {1, 1, 2, 3, 5, 8}; |
static const int test_vals[] = {1, 2, 3, 5, 8}; |
- std::vector<int> my_set(vals, vals + 6); |
- std::vector<int> test_set(test_vals, test_vals + 5); |
- const Matcher<std::vector<int> > m = ContainerEq(my_set); |
+ vector<int> my_set(vals, vals + 6); |
+ vector<int> test_set(test_vals, test_vals + 5); |
+ const Matcher<vector<int> > m = ContainerEq(my_set); |
EXPECT_TRUE(m.Matches(my_set)); |
EXPECT_FALSE(m.Matches(test_set)); |
// There is nothing to report when both sets contain all the same values. |
@@ -3564,15 +3572,15 @@ TEST(ContainerEqExtraTest, MultiSetOfIntDuplicateDifference) { |
// Tests that ContainerEq works for non-trivial associative containers, |
// like maps. |
TEST(ContainerEqExtraTest, WorksForMaps) { |
- std::map<int, std::string> my_map; |
+ map<int, std::string> my_map; |
my_map[0] = "a"; |
my_map[1] = "b"; |
- std::map<int, std::string> test_map; |
+ map<int, std::string> test_map; |
test_map[0] = "aa"; |
test_map[1] = "b"; |
- const Matcher<const std::map<int, std::string>&> m = ContainerEq(my_map); |
+ const Matcher<const map<int, std::string>&> m = ContainerEq(my_map); |
EXPECT_TRUE(m.Matches(my_map)); |
EXPECT_FALSE(m.Matches(test_map)); |
@@ -3984,5 +3992,209 @@ TEST(MatcherTupleTest, ExplainsMatchFailure) { |
// explanation. |
} |
+// Tests Each(). |
+ |
+TEST(EachTest, ExplainsMatchResultCorrectly) { |
+ set<int> a; // empty |
+ |
+ Matcher<set<int> > m = Each(2); |
+ EXPECT_EQ("", Explain(m, a)); |
+ |
+ Matcher<const int(&)[1]> n = Each(1); |
+ |
+ const int b[1] = { 1 }; |
+ EXPECT_EQ("", Explain(n, b)); |
+ |
+ n = Each(3); |
+ EXPECT_EQ("whose element #0 doesn't match", Explain(n, b)); |
+ |
+ a.insert(1); |
+ a.insert(2); |
+ a.insert(3); |
+ m = Each(GreaterThan(0)); |
+ EXPECT_EQ("", Explain(m, a)); |
+ |
+ m = Each(GreaterThan(10)); |
+ EXPECT_EQ("whose element #0 doesn't match, which is 9 less than 10", |
+ Explain(m, a)); |
+} |
+ |
+TEST(EachTest, DescribesItselfCorrectly) { |
+ Matcher<vector<int> > m = Each(1); |
+ EXPECT_EQ("only contains elements that is equal to 1", Describe(m)); |
+ |
+ Matcher<vector<int> > m2 = Not(m); |
+ EXPECT_EQ("contains some element that isn't equal to 1", Describe(m2)); |
+} |
+ |
+TEST(EachTest, MatchesVectorWhenAllElementsMatch) { |
+ vector<int> some_vector; |
+ EXPECT_THAT(some_vector, Each(1)); |
+ some_vector.push_back(3); |
+ EXPECT_THAT(some_vector, Not(Each(1))); |
+ EXPECT_THAT(some_vector, Each(3)); |
+ some_vector.push_back(1); |
+ some_vector.push_back(2); |
+ EXPECT_THAT(some_vector, Not(Each(3))); |
+ EXPECT_THAT(some_vector, Each(Lt(3.5))); |
+ |
+ vector<string> another_vector; |
+ another_vector.push_back("fee"); |
+ EXPECT_THAT(another_vector, Each(string("fee"))); |
+ another_vector.push_back("fie"); |
+ another_vector.push_back("foe"); |
+ another_vector.push_back("fum"); |
+ EXPECT_THAT(another_vector, Not(Each(string("fee")))); |
+} |
+ |
+TEST(EachTest, MatchesMapWhenAllElementsMatch) { |
+ map<const char*, int> my_map; |
+ const char* bar = "a string"; |
+ my_map[bar] = 2; |
+ EXPECT_THAT(my_map, Each(make_pair(bar, 2))); |
+ |
+ map<string, int> another_map; |
+ EXPECT_THAT(another_map, Each(make_pair(string("fee"), 1))); |
+ another_map["fee"] = 1; |
+ EXPECT_THAT(another_map, Each(make_pair(string("fee"), 1))); |
+ another_map["fie"] = 2; |
+ another_map["foe"] = 3; |
+ another_map["fum"] = 4; |
+ EXPECT_THAT(another_map, Not(Each(make_pair(string("fee"), 1)))); |
+ EXPECT_THAT(another_map, Not(Each(make_pair(string("fum"), 1)))); |
+ EXPECT_THAT(another_map, Each(Pair(_, Gt(0)))); |
+} |
+ |
+TEST(EachTest, AcceptsMatcher) { |
+ const int a[] = { 1, 2, 3 }; |
+ EXPECT_THAT(a, Each(Gt(0))); |
+ EXPECT_THAT(a, Not(Each(Gt(1)))); |
+} |
+ |
+TEST(EachTest, WorksForNativeArrayAsTuple) { |
+ const int a[] = { 1, 2 }; |
+ const int* const pointer = a; |
+ EXPECT_THAT(make_tuple(pointer, 2), Each(Gt(0))); |
+ EXPECT_THAT(make_tuple(pointer, 2), Not(Each(Gt(1)))); |
+} |
+ |
+// For testing Pointwise(). |
+class IsHalfOfMatcher { |
+ public: |
+ template <typename T1, typename T2> |
+ bool MatchAndExplain(const tuple<T1, T2>& a_pair, |
+ MatchResultListener* listener) const { |
+ if (get<0>(a_pair) == get<1>(a_pair)/2) { |
+ *listener << "where the second is " << get<1>(a_pair); |
+ return true; |
+ } else { |
+ *listener << "where the second/2 is " << get<1>(a_pair)/2; |
+ return false; |
+ } |
+ } |
+ |
+ void DescribeTo(ostream* os) const { |
+ *os << "are a pair where the first is half of the second"; |
+ } |
+ |
+ void DescribeNegationTo(ostream* os) const { |
+ *os << "are a pair where the first isn't half of the second"; |
+ } |
+}; |
+ |
+PolymorphicMatcher<IsHalfOfMatcher> IsHalfOf() { |
+ return MakePolymorphicMatcher(IsHalfOfMatcher()); |
+} |
+ |
+TEST(PointwiseTest, DescribesSelf) { |
+ vector<int> rhs; |
+ rhs.push_back(1); |
+ rhs.push_back(2); |
+ rhs.push_back(3); |
+ const Matcher<const vector<int>&> m = Pointwise(IsHalfOf(), rhs); |
+ EXPECT_EQ("contains 3 values, where each value and its corresponding value " |
+ "in { 1, 2, 3 } are a pair where the first is half of the second", |
+ Describe(m)); |
+ EXPECT_EQ("doesn't contain exactly 3 values, or contains a value x at some " |
+ "index i where x and the i-th value of { 1, 2, 3 } are a pair " |
+ "where the first isn't half of the second", |
+ DescribeNegation(m)); |
+} |
+ |
+TEST(PointwiseTest, MakesCopyOfRhs) { |
+ list<signed char> rhs; |
+ rhs.push_back(2); |
+ rhs.push_back(4); |
+ |
+ int lhs[] = { 1, 2 }; |
+ const Matcher<const int (&)[2]> m = Pointwise(IsHalfOf(), rhs); |
+ EXPECT_THAT(lhs, m); |
+ |
+ // Changing rhs now shouldn't affect m, which made a copy of rhs. |
+ rhs.push_back(6); |
+ EXPECT_THAT(lhs, m); |
+} |
+ |
+TEST(PointwiseTest, WorksForLhsNativeArray) { |
+ const int lhs[] = { 1, 2, 3 }; |
+ vector<int> rhs; |
+ rhs.push_back(2); |
+ rhs.push_back(4); |
+ rhs.push_back(6); |
+ EXPECT_THAT(lhs, Pointwise(Lt(), rhs)); |
+ EXPECT_THAT(lhs, Not(Pointwise(Gt(), rhs))); |
+} |
+ |
+TEST(PointwiseTest, WorksForRhsNativeArray) { |
+ const int rhs[] = { 1, 2, 3 }; |
+ vector<int> lhs; |
+ lhs.push_back(2); |
+ lhs.push_back(4); |
+ lhs.push_back(6); |
+ EXPECT_THAT(lhs, Pointwise(Gt(), rhs)); |
+ EXPECT_THAT(lhs, Not(Pointwise(Lt(), rhs))); |
+} |
+ |
+TEST(PointwiseTest, RejectsWrongSize) { |
+ const double lhs[2] = { 1, 2 }; |
+ const int rhs[1] = { 0 }; |
+ EXPECT_THAT(lhs, Not(Pointwise(Gt(), rhs))); |
+ EXPECT_EQ("which contains 2 values", |
+ Explain(Pointwise(Gt(), rhs), lhs)); |
+ |
+ const int rhs2[3] = { 0, 1, 2 }; |
+ EXPECT_THAT(lhs, Not(Pointwise(Gt(), rhs2))); |
+} |
+ |
+TEST(PointwiseTest, RejectsWrongContent) { |
+ const double lhs[3] = { 1, 2, 3 }; |
+ const int rhs[3] = { 2, 6, 4 }; |
+ EXPECT_THAT(lhs, Not(Pointwise(IsHalfOf(), rhs))); |
+ EXPECT_EQ("where the value pair (2, 6) at index #1 don't match, " |
+ "where the second/2 is 3", |
+ Explain(Pointwise(IsHalfOf(), rhs), lhs)); |
+} |
+ |
+TEST(PointwiseTest, AcceptsCorrectContent) { |
+ const double lhs[3] = { 1, 2, 3 }; |
+ const int rhs[3] = { 2, 4, 6 }; |
+ EXPECT_THAT(lhs, Pointwise(IsHalfOf(), rhs)); |
+ EXPECT_EQ("", Explain(Pointwise(IsHalfOf(), rhs), lhs)); |
+} |
+ |
+TEST(PointwiseTest, AllowsMonomorphicInnerMatcher) { |
+ const double lhs[3] = { 1, 2, 3 }; |
+ const int rhs[3] = { 2, 4, 6 }; |
+ const Matcher<tuple<const double&, const int&> > m1 = IsHalfOf(); |
+ EXPECT_THAT(lhs, Pointwise(m1, rhs)); |
+ EXPECT_EQ("", Explain(Pointwise(m1, rhs), lhs)); |
+ |
+ // This type works as a tuple<const double&, const int&> can be |
+ // implicitly cast to tuple<double, int>. |
+ const Matcher<tuple<double, int> > m2 = IsHalfOf(); |
+ EXPECT_THAT(lhs, Pointwise(m2, rhs)); |
+ EXPECT_EQ("", Explain(Pointwise(m2, rhs), lhs)); |
+} |
+ |
} // namespace gmock_matchers_test |
} // namespace testing |