summaryrefslogtreecommitdiffstats
path: root/testing/gmock/test/gmock-matchers_test.cc
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-16 19:50:59 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-16 19:50:59 +0000
commiteac1cd26a7fec8261bbe60f2aed21e01368e4af6 (patch)
tree133bdf2b91537dffe84dcf90cfaf712ce7259c32 /testing/gmock/test/gmock-matchers_test.cc
parentbb415723ffe8794f16c6639738066061d4f97288 (diff)
downloadchromium_src-eac1cd26a7fec8261bbe60f2aed21e01368e4af6.zip
chromium_src-eac1cd26a7fec8261bbe60f2aed21e01368e4af6.tar.gz
chromium_src-eac1cd26a7fec8261bbe60f2aed21e01368e4af6.tar.bz2
clang: update gtest to r435 and gmock to r300.
This picks up some clang-specific fixes. Unfortunately, the gtest update cascaded into a gmock update. So I picked the earliest gmock version that mentioned a specific gtest version so that they are more likely to work together. gtest changelog: - Fixes a leak in ThreadLocal. - CMake 2.8/Visual Age compatibility patch by Hady Zalek. - C++ Builder compatibility patch by Josh Kelley. - Fixes gtest_filter_unittest and gtest_help_test on systems without death tests. - Simplifies Makefile.am (by Zhanyong Wan and Vlad Losev). - Adds alternative spellings for FAIL, SUCCEED, and TEST. - Over-hauls README, and fixes Makefile. - Fixes gtest-port_test on MinGW. - Implements color output in GNU Screen sessions (issue 277). - Minor improvement to hermetic build support in the CMake script, by Vlad Losev. - Improves support for building Google Test as Windows DLL. - Silence a Clang warning about an unused variable. - Moves the universal printer from gmock to gtest and refactors the cmake script for reusing in gmock (by Vlad Losev). - Suppresses some Clang warnings (by Chandler Carruth, Jeffrey Yasskin, and Zhanyong Wan). - Renames CMake build script options. - Lucid autotools compatibility patch by Jeffrey Yasskin. - Replaces UniversalPrinter<T>::Print(x, os) with UniversalPrint(x, os) as appropriate (by Zhanyong Wan). - Comment tweaks in CMakeLists.txt. - Renames test script flags. - Fixes a typo in comments. - Adds GTEST_REMOVE_REFERENCE_AND_CONST_. - Introduces gtest_force_shared_crt option for CMake build scripts. - Implements printing parameters of failed parameterized tests (issue 71). gmock changelog: - Improves Makefile.am (by Vlad Losev); fixes Makefile and updates README (by Zhanyong Wan). - Fixes a typo in README. - Adds Each(m) (by Wojtek Moczydlowski); removes scripts/test/Makefile (by Zhanyong Wan); pulls in gtest r424. - Adds a synchronization test. - Fixes tests leaking altered values of GMOCK_FLAG(verbose) (issue 110). - Moves the universal printer from gmock to gtest (by Vlad Losev). - Renames test script flags. - Adds CMake build script. - Implements Pointwise(). - Fixes build failure on Windows/CMake (issue 111). - Pulls r435 of gtest. This brings in the gtest_force_shared_crt option in CMake. TEST=all existing tests should still pass Review URL: http://codereview.chromium.org/3427004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59701 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'testing/gmock/test/gmock-matchers_test.cc')
-rw-r--r--testing/gmock/test/gmock-matchers_test.cc304
1 files changed, 258 insertions, 46 deletions
diff --git a/testing/gmock/test/gmock-matchers_test.cc b/testing/gmock/test/gmock-matchers_test.cc
index 6d784f1..3b151db 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