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>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const {
|
||||||
return MakeMatcher(new Impl<Container>(size_matcher_));
|
return Matcher<Container>(new Impl<const Container&>(size_matcher_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
@ -2009,7 +2009,7 @@ class BeginEndDistanceIsMatcher {
|
|||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const {
|
||||||
return MakeMatcher(new Impl<Container>(distance_matcher_));
|
return Matcher<Container>(new Impl<const Container&>(distance_matcher_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
@ -2269,7 +2269,8 @@ class PointwiseMatcher {
|
|||||||
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,
|
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,
|
||||||
use_UnorderedPointwise_with_hash_tables);
|
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>
|
template <typename LhsContainer>
|
||||||
@ -2471,7 +2472,8 @@ class ContainsMatcher {
|
|||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const {
|
||||||
return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_));
|
return Matcher<Container>(
|
||||||
|
new ContainsMatcherImpl<const Container&>(inner_matcher_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2488,7 +2490,8 @@ class EachMatcher {
|
|||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const {
|
||||||
return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_));
|
return Matcher<Container>(
|
||||||
|
new EachMatcherImpl<const Container&>(inner_matcher_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -3086,8 +3089,10 @@ class UnorderedElementsAreMatcher {
|
|||||||
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
||||||
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
||||||
::std::back_inserter(matchers));
|
::std::back_inserter(matchers));
|
||||||
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
return Matcher<Container>(
|
||||||
UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end()));
|
new UnorderedElementsAreMatcherImpl<const Container&>(
|
||||||
|
UnorderedMatcherRequire::ExactMatch, matchers.begin(),
|
||||||
|
matchers.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -3116,8 +3121,8 @@ class ElementsAreMatcher {
|
|||||||
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
||||||
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
||||||
::std::back_inserter(matchers));
|
::std::back_inserter(matchers));
|
||||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(
|
return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
|
||||||
matchers.begin(), matchers.end()));
|
matchers.begin(), matchers.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -3136,8 +3141,9 @@ class UnorderedElementsAreArrayMatcher {
|
|||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const {
|
||||||
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
return Matcher<Container>(
|
||||||
match_flags_, matchers_.begin(), matchers_.end()));
|
new UnorderedElementsAreMatcherImpl<const Container&>(
|
||||||
|
match_flags_, matchers_.begin(), matchers_.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -3160,7 +3166,7 @@ class ElementsAreArrayMatcher {
|
|||||||
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
|
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
|
||||||
use_UnorderedElementsAreArray_with_hash_tables);
|
use_UnorderedElementsAreArray_with_hash_tables);
|
||||||
|
|
||||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(
|
return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
|
||||||
matchers_.begin(), matchers_.end()));
|
matchers_.begin(), matchers_.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace gmock_matchers_test {
|
namespace gmock_matchers_test {
|
||||||
|
namespace {
|
||||||
|
|
||||||
using std::greater;
|
using std::greater;
|
||||||
using std::less;
|
using std::less;
|
||||||
@ -158,6 +159,19 @@ using testing::internal::StreamMatchResultListener;
|
|||||||
using testing::internal::string;
|
using testing::internal::string;
|
||||||
using testing::internal::Strings;
|
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().
|
// For testing ExplainMatchResultTo().
|
||||||
class GreaterThanMatcher : public MatcherInterface<int> {
|
class GreaterThanMatcher : public MatcherInterface<int> {
|
||||||
public:
|
public:
|
||||||
@ -1679,6 +1693,12 @@ TEST(PairTest, InsideContainsUsingMap) {
|
|||||||
EXPECT_THAT(container, Not(Contains(Pair(3, _))));
|
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
|
#if GTEST_LANG_CXX11
|
||||||
TEST(PairTest, UseGetInsteadOfMembers) {
|
TEST(PairTest, UseGetInsteadOfMembers) {
|
||||||
PairWithGet pair{7, "ABC"};
|
PairWithGet pair{7, "ABC"};
|
||||||
@ -4752,6 +4772,12 @@ TEST(IsEmptyTest, ExplainsResult) {
|
|||||||
EXPECT_EQ("whose size is 1", Explain(m, container));
|
EXPECT_EQ("whose size is 1", Explain(m, container));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(IsEmptyTest, WorksWithMoveOnly) {
|
||||||
|
ContainerHelper helper;
|
||||||
|
EXPECT_CALL(helper, Call(IsEmpty()));
|
||||||
|
helper.Call({});
|
||||||
|
}
|
||||||
|
|
||||||
TEST(IsTrueTest, IsTrueIsFalse) {
|
TEST(IsTrueTest, IsTrueIsFalse) {
|
||||||
EXPECT_THAT(true, IsTrue());
|
EXPECT_THAT(true, IsTrue());
|
||||||
EXPECT_THAT(false, IsFalse());
|
EXPECT_THAT(false, IsFalse());
|
||||||
@ -4822,6 +4848,12 @@ TEST(SizeIsTest, WorksWithReferences) {
|
|||||||
EXPECT_THAT(container, m);
|
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.
|
// 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.
|
// For example, a size_type member type should not need to be provided.
|
||||||
struct MinimalistCustomType {
|
struct MinimalistCustomType {
|
||||||
@ -5308,6 +5340,12 @@ TEST(BeginEndDistanceIsTest, CanDescribeSelf) {
|
|||||||
DescribeNegation(m));
|
DescribeNegation(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(BeginEndDistanceIsTest, WorksWithMoveOnly) {
|
||||||
|
ContainerHelper helper;
|
||||||
|
EXPECT_CALL(helper, Call(BeginEndDistanceIs(2)));
|
||||||
|
helper.Call(MakeUniquePtrs({1, 2}));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(BeginEndDistanceIsTest, ExplainsResult) {
|
TEST(BeginEndDistanceIsTest, ExplainsResult) {
|
||||||
Matcher<vector<int> > m1 = BeginEndDistanceIs(2);
|
Matcher<vector<int> > m1 = BeginEndDistanceIs(2);
|
||||||
Matcher<vector<int> > m2 = BeginEndDistanceIs(Lt(2));
|
Matcher<vector<int> > m2 = BeginEndDistanceIs(Lt(2));
|
||||||
@ -5477,6 +5515,14 @@ TEST(IsSupersetOfTest, WorksForRhsInitializerList) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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) {
|
TEST(IsSubsetOfTest, WorksForNativeArray) {
|
||||||
const int subset[] = {1, 4};
|
const int subset[] = {1, 4};
|
||||||
const int superset[] = {1, 2, 4};
|
const int superset[] = {1, 2, 4};
|
||||||
@ -5599,6 +5645,14 @@ TEST(IsSubsetOfTest, WorksForRhsInitializerList) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
// Tests using ElementsAre() and ElementsAreArray() with stream-like
|
||||||
// "containers".
|
// "containers".
|
||||||
|
|
||||||
@ -5632,6 +5686,15 @@ TEST(ElementsAreTest, WorksWithUncopyable) {
|
|||||||
EXPECT_THAT(objs, ElementsAre(UncopyableIs(-3), Truly(ValueIsPositive)));
|
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) {
|
TEST(ElementsAreTest, TakesStlContainer) {
|
||||||
const int actual[] = {3, 1, 2};
|
const int actual[] = {3, 1, 2};
|
||||||
|
|
||||||
@ -5735,6 +5798,13 @@ TEST(UnorderedElementsAreArrayTest,
|
|||||||
|
|
||||||
#endif // GTEST_HAS_STD_INITIALIZER_LIST_
|
#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 {
|
class UnorderedElementsAreTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
typedef std::vector<int> IntVec;
|
typedef std::vector<int> IntVec;
|
||||||
@ -5782,6 +5852,12 @@ TEST_F(UnorderedElementsAreTest, WorksForStreamlike) {
|
|||||||
EXPECT_THAT(s, Not(UnorderedElementsAre(2, 2, 3, 4, 5)));
|
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
|
// 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
|
// 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
|
// 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))));
|
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().
|
// For testing Pointwise().
|
||||||
class IsHalfOfMatcher {
|
class IsHalfOfMatcher {
|
||||||
public:
|
public:
|
||||||
@ -6470,6 +6552,17 @@ TEST(PointwiseTest, AllowsMonomorphicInnerMatcher) {
|
|||||||
EXPECT_EQ("", Explain(Pointwise(m2, rhs), lhs));
|
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) {
|
TEST(UnorderedPointwiseTest, DescribesSelf) {
|
||||||
vector<int> rhs;
|
vector<int> rhs;
|
||||||
rhs.push_back(1);
|
rhs.push_back(1);
|
||||||
@ -6584,6 +6677,13 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) {
|
|||||||
EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs));
|
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
|
// Sample optional type implementation with minimal requirements for use with
|
||||||
// Optional matcher.
|
// Optional matcher.
|
||||||
class SampleOptionalInt {
|
class SampleOptionalInt {
|
||||||
@ -6976,8 +7076,7 @@ TEST_F(PredicateFormatterFromMatcherTest, NoShortCircuitOnFailure) {
|
|||||||
EXPECT_FALSE(result); // Implicit cast to bool.
|
EXPECT_FALSE(result); // Implicit cast to bool.
|
||||||
std::string expect =
|
std::string expect =
|
||||||
"Value of: dummy-name\nExpected: [DescribeTo]\n"
|
"Value of: dummy-name\nExpected: [DescribeTo]\n"
|
||||||
" Actual: 1" +
|
" Actual: 1, [MatchAndExplain]";
|
||||||
OfType(kMatcherType) + ", [MatchAndExplain]";
|
|
||||||
EXPECT_EQ(expect, result.message());
|
EXPECT_EQ(expect, result.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6988,11 +7087,11 @@ TEST_F(PredicateFormatterFromMatcherTest, DetectsFlakyShortCircuit) {
|
|||||||
"Value of: dummy-name\nExpected: [DescribeTo]\n"
|
"Value of: dummy-name\nExpected: [DescribeTo]\n"
|
||||||
" The matcher failed on the initial attempt; but passed when rerun to "
|
" The matcher failed on the initial attempt; but passed when rerun to "
|
||||||
"generate the explanation.\n"
|
"generate the explanation.\n"
|
||||||
" Actual: 2" +
|
" Actual: 2, [MatchAndExplain]";
|
||||||
OfType(kMatcherType) + ", [MatchAndExplain]";
|
|
||||||
EXPECT_EQ(expect, result.message());
|
EXPECT_EQ(expect, result.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
} // namespace gmock_matchers_test
|
} // namespace gmock_matchers_test
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user