Googletest export
Allow container matchers to accept move-only containers. PiperOrigin-RevId: 225667441
This commit is contained in:
parent
096fb37a19
commit
1ec20f87e3
@ -1959,7 +1959,7 @@ class SizeIsMatcher {
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
return MakeMatcher(new Impl<Container>(size_matcher_));
|
||||
return Matcher<Container>(new Impl<const Container&>(size_matcher_));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
@ -2009,7 +2009,7 @@ class BeginEndDistanceIsMatcher {
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
return MakeMatcher(new Impl<Container>(distance_matcher_));
|
||||
return Matcher<Container>(new Impl<const Container&>(distance_matcher_));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
@ -2269,7 +2269,8 @@ class PointwiseMatcher {
|
||||
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,
|
||||
use_UnorderedPointwise_with_hash_tables);
|
||||
|
||||
return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_));
|
||||
return Matcher<LhsContainer>(
|
||||
new Impl<const LhsContainer&>(tuple_matcher_, rhs_));
|
||||
}
|
||||
|
||||
template <typename LhsContainer>
|
||||
@ -2471,7 +2472,8 @@ class ContainsMatcher {
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_));
|
||||
return Matcher<Container>(
|
||||
new ContainsMatcherImpl<const Container&>(inner_matcher_));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2488,7 +2490,8 @@ class EachMatcher {
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_));
|
||||
return Matcher<Container>(
|
||||
new EachMatcherImpl<const Container&>(inner_matcher_));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -3086,8 +3089,10 @@ class UnorderedElementsAreMatcher {
|
||||
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
||||
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
||||
::std::back_inserter(matchers));
|
||||
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
||||
UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end()));
|
||||
return Matcher<Container>(
|
||||
new UnorderedElementsAreMatcherImpl<const Container&>(
|
||||
UnorderedMatcherRequire::ExactMatch, matchers.begin(),
|
||||
matchers.end()));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -3116,7 +3121,7 @@ class ElementsAreMatcher {
|
||||
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
||||
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
||||
::std::back_inserter(matchers));
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(
|
||||
return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
|
||||
matchers.begin(), matchers.end()));
|
||||
}
|
||||
|
||||
@ -3136,7 +3141,8 @@ class UnorderedElementsAreArrayMatcher {
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
||||
return Matcher<Container>(
|
||||
new UnorderedElementsAreMatcherImpl<const Container&>(
|
||||
match_flags_, matchers_.begin(), matchers_.end()));
|
||||
}
|
||||
|
||||
@ -3160,7 +3166,7 @@ class ElementsAreArrayMatcher {
|
||||
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
|
||||
use_UnorderedElementsAreArray_with_hash_tables);
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(
|
||||
return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
|
||||
matchers_.begin(), matchers_.end()));
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_matchers_test {
|
||||
namespace {
|
||||
|
||||
using std::greater;
|
||||
using std::less;
|
||||
@ -158,6 +159,19 @@ using testing::internal::StreamMatchResultListener;
|
||||
using testing::internal::string;
|
||||
using testing::internal::Strings;
|
||||
|
||||
// Helper for testing container-valued matchers in mock method context. It is
|
||||
// important to test matchers in this context, since it requires additional type
|
||||
// deduction beyond what EXPECT_THAT does, thus making it more restrictive.
|
||||
struct ContainerHelper {
|
||||
MOCK_METHOD1(Call, void(std::vector<std::unique_ptr<int>>));
|
||||
};
|
||||
|
||||
std::vector<std::unique_ptr<int>> MakeUniquePtrs(const std::vector<int>& ints) {
|
||||
std::vector<std::unique_ptr<int>> pointers;
|
||||
for (int i : ints) pointers.emplace_back(new int(i));
|
||||
return pointers;
|
||||
}
|
||||
|
||||
// For testing ExplainMatchResultTo().
|
||||
class GreaterThanMatcher : public MatcherInterface<int> {
|
||||
public:
|
||||
@ -1679,6 +1693,12 @@ TEST(PairTest, InsideContainsUsingMap) {
|
||||
EXPECT_THAT(container, Not(Contains(Pair(3, _))));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(Contains(Pointee(2))));
|
||||
helper.Call(MakeUniquePtrs({1, 2}));
|
||||
}
|
||||
|
||||
#if GTEST_LANG_CXX11
|
||||
TEST(PairTest, UseGetInsteadOfMembers) {
|
||||
PairWithGet pair{7, "ABC"};
|
||||
@ -4752,6 +4772,12 @@ TEST(IsEmptyTest, ExplainsResult) {
|
||||
EXPECT_EQ("whose size is 1", Explain(m, container));
|
||||
}
|
||||
|
||||
TEST(IsEmptyTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(IsEmpty()));
|
||||
helper.Call({});
|
||||
}
|
||||
|
||||
TEST(IsTrueTest, IsTrueIsFalse) {
|
||||
EXPECT_THAT(true, IsTrue());
|
||||
EXPECT_THAT(false, IsFalse());
|
||||
@ -4822,6 +4848,12 @@ TEST(SizeIsTest, WorksWithReferences) {
|
||||
EXPECT_THAT(container, m);
|
||||
}
|
||||
|
||||
TEST(SizeIsTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(SizeIs(3)));
|
||||
helper.Call(MakeUniquePtrs({1, 2, 3}));
|
||||
}
|
||||
|
||||
// SizeIs should work for any type that provides a size() member function.
|
||||
// For example, a size_type member type should not need to be provided.
|
||||
struct MinimalistCustomType {
|
||||
@ -5308,6 +5340,12 @@ TEST(BeginEndDistanceIsTest, CanDescribeSelf) {
|
||||
DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(BeginEndDistanceIsTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(BeginEndDistanceIs(2)));
|
||||
helper.Call(MakeUniquePtrs({1, 2}));
|
||||
}
|
||||
|
||||
TEST(BeginEndDistanceIsTest, ExplainsResult) {
|
||||
Matcher<vector<int> > m1 = BeginEndDistanceIs(2);
|
||||
Matcher<vector<int> > m2 = BeginEndDistanceIs(Lt(2));
|
||||
@ -5477,6 +5515,14 @@ TEST(IsSupersetOfTest, WorksForRhsInitializerList) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(IsSupersetOfTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(IsSupersetOf({Pointee(1)})));
|
||||
helper.Call(MakeUniquePtrs({1, 2}));
|
||||
EXPECT_CALL(helper, Call(Not(IsSupersetOf({Pointee(1), Pointee(2)}))));
|
||||
helper.Call(MakeUniquePtrs({2}));
|
||||
}
|
||||
|
||||
TEST(IsSubsetOfTest, WorksForNativeArray) {
|
||||
const int subset[] = {1, 4};
|
||||
const int superset[] = {1, 2, 4};
|
||||
@ -5599,6 +5645,14 @@ TEST(IsSubsetOfTest, WorksForRhsInitializerList) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(IsSubsetOfTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(IsSubsetOf({Pointee(1), Pointee(2)})));
|
||||
helper.Call(MakeUniquePtrs({1}));
|
||||
EXPECT_CALL(helper, Call(Not(IsSubsetOf({Pointee(1)}))));
|
||||
helper.Call(MakeUniquePtrs({2}));
|
||||
}
|
||||
|
||||
// Tests using ElementsAre() and ElementsAreArray() with stream-like
|
||||
// "containers".
|
||||
|
||||
@ -5632,6 +5686,15 @@ TEST(ElementsAreTest, WorksWithUncopyable) {
|
||||
EXPECT_THAT(objs, ElementsAre(UncopyableIs(-3), Truly(ValueIsPositive)));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(ElementsAre(Pointee(1), Pointee(2))));
|
||||
helper.Call(MakeUniquePtrs({1, 2}));
|
||||
|
||||
EXPECT_CALL(helper, Call(ElementsAreArray({Pointee(3), Pointee(4)})));
|
||||
helper.Call(MakeUniquePtrs({3, 4}));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, TakesStlContainer) {
|
||||
const int actual[] = {3, 1, 2};
|
||||
|
||||
@ -5735,6 +5798,13 @@ TEST(UnorderedElementsAreArrayTest,
|
||||
|
||||
#endif // GTEST_HAS_STD_INITIALIZER_LIST_
|
||||
|
||||
TEST(UnorderedElementsAreArrayTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper,
|
||||
Call(UnorderedElementsAreArray({Pointee(1), Pointee(2)})));
|
||||
helper.Call(MakeUniquePtrs({2, 1}));
|
||||
}
|
||||
|
||||
class UnorderedElementsAreTest : public testing::Test {
|
||||
protected:
|
||||
typedef std::vector<int> IntVec;
|
||||
@ -5782,6 +5852,12 @@ TEST_F(UnorderedElementsAreTest, WorksForStreamlike) {
|
||||
EXPECT_THAT(s, Not(UnorderedElementsAre(2, 2, 3, 4, 5)));
|
||||
}
|
||||
|
||||
TEST_F(UnorderedElementsAreTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(UnorderedElementsAre(Pointee(1), Pointee(2))));
|
||||
helper.Call(MakeUniquePtrs({2, 1}));
|
||||
}
|
||||
|
||||
// One naive implementation of the matcher runs in O(N!) time, which is too
|
||||
// slow for many real-world inputs. This test shows that our matcher can match
|
||||
// 100 inputs very quickly (a few milliseconds). An O(100!) is 10^158
|
||||
@ -6332,6 +6408,12 @@ TEST(EachTest, WorksForNativeArrayAsTuple) {
|
||||
EXPECT_THAT(std::make_tuple(pointer, 2), Not(Each(Gt(1))));
|
||||
}
|
||||
|
||||
TEST(EachTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(Each(Pointee(Gt(0)))));
|
||||
helper.Call(MakeUniquePtrs({1, 2}));
|
||||
}
|
||||
|
||||
// For testing Pointwise().
|
||||
class IsHalfOfMatcher {
|
||||
public:
|
||||
@ -6470,6 +6552,17 @@ TEST(PointwiseTest, AllowsMonomorphicInnerMatcher) {
|
||||
EXPECT_EQ("", Explain(Pointwise(m2, rhs), lhs));
|
||||
}
|
||||
|
||||
MATCHER(PointeeEquals, "Points to an equal value") {
|
||||
return ExplainMatchResult(::testing::Pointee(::testing::get<1>(arg)),
|
||||
::testing::get<0>(arg), result_listener);
|
||||
}
|
||||
|
||||
TEST(PointwiseTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(Pointwise(PointeeEquals(), std::vector<int>{1, 2})));
|
||||
helper.Call(MakeUniquePtrs({1, 2}));
|
||||
}
|
||||
|
||||
TEST(UnorderedPointwiseTest, DescribesSelf) {
|
||||
vector<int> rhs;
|
||||
rhs.push_back(1);
|
||||
@ -6584,6 +6677,13 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) {
|
||||
EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs));
|
||||
}
|
||||
|
||||
TEST(UnorderedPointwiseTest, WorksWithMoveOnly) {
|
||||
ContainerHelper helper;
|
||||
EXPECT_CALL(helper, Call(UnorderedPointwise(PointeeEquals(),
|
||||
std::vector<int>{1, 2})));
|
||||
helper.Call(MakeUniquePtrs({2, 1}));
|
||||
}
|
||||
|
||||
// Sample optional type implementation with minimal requirements for use with
|
||||
// Optional matcher.
|
||||
class SampleOptionalInt {
|
||||
@ -6976,8 +7076,7 @@ TEST_F(PredicateFormatterFromMatcherTest, NoShortCircuitOnFailure) {
|
||||
EXPECT_FALSE(result); // Implicit cast to bool.
|
||||
std::string expect =
|
||||
"Value of: dummy-name\nExpected: [DescribeTo]\n"
|
||||
" Actual: 1" +
|
||||
OfType(kMatcherType) + ", [MatchAndExplain]";
|
||||
" Actual: 1, [MatchAndExplain]";
|
||||
EXPECT_EQ(expect, result.message());
|
||||
}
|
||||
|
||||
@ -6988,11 +7087,11 @@ TEST_F(PredicateFormatterFromMatcherTest, DetectsFlakyShortCircuit) {
|
||||
"Value of: dummy-name\nExpected: [DescribeTo]\n"
|
||||
" The matcher failed on the initial attempt; but passed when rerun to "
|
||||
"generate the explanation.\n"
|
||||
" Actual: 2" +
|
||||
OfType(kMatcherType) + ", [MatchAndExplain]";
|
||||
" Actual: 2, [MatchAndExplain]";
|
||||
EXPECT_EQ(expect, result.message());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user