Googletest export
Add move-only argument support to almost all remaining matchers. PiperOrigin-RevId: 229030728
This commit is contained in:
parent
097407fd3c
commit
9acd065a90
|
@ -900,7 +900,7 @@ class PairMatchBase {
|
|||
public:
|
||||
template <typename T1, typename T2>
|
||||
operator Matcher<::std::tuple<T1, T2>>() const {
|
||||
return MakeMatcher(new Impl<::std::tuple<T1, T2>>);
|
||||
return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>);
|
||||
}
|
||||
template <typename T1, typename T2>
|
||||
operator Matcher<const ::std::tuple<T1, T2>&>() const {
|
||||
|
@ -2535,7 +2535,8 @@ class KeyMatcher {
|
|||
|
||||
template <typename PairType>
|
||||
operator Matcher<PairType>() const {
|
||||
return MakeMatcher(new KeyMatcherImpl<PairType>(matcher_for_key_));
|
||||
return Matcher<PairType>(
|
||||
new KeyMatcherImpl<const PairType&>(matcher_for_key_));
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -2640,9 +2641,8 @@ class PairMatcher {
|
|||
|
||||
template <typename PairType>
|
||||
operator Matcher<PairType> () const {
|
||||
return MakeMatcher(
|
||||
new PairMatcherImpl<PairType>(
|
||||
first_matcher_, second_matcher_));
|
||||
return Matcher<PairType>(
|
||||
new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_));
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -3205,7 +3205,7 @@ class OptionalMatcher {
|
|||
|
||||
template <typename Optional>
|
||||
operator Matcher<Optional>() const {
|
||||
return MakeMatcher(new Impl<Optional>(value_matcher_));
|
||||
return Matcher<Optional>(new Impl<const Optional&>(value_matcher_));
|
||||
}
|
||||
|
||||
template <typename Optional>
|
||||
|
|
|
@ -1095,6 +1095,47 @@ TEST(NeTest, CanDescribeSelf) {
|
|||
EXPECT_EQ("isn't equal to 5", Describe(m));
|
||||
}
|
||||
|
||||
class MoveOnly {
|
||||
public:
|
||||
explicit MoveOnly(int i) : i_(i) {}
|
||||
MoveOnly(const MoveOnly&) = delete;
|
||||
MoveOnly(MoveOnly&&) = default;
|
||||
MoveOnly& operator=(const MoveOnly&) = delete;
|
||||
MoveOnly& operator=(MoveOnly&&) = default;
|
||||
|
||||
bool operator==(const MoveOnly& other) const { return i_ == other.i_; }
|
||||
bool operator!=(const MoveOnly& other) const { return i_ != other.i_; }
|
||||
bool operator<(const MoveOnly& other) const { return i_ < other.i_; }
|
||||
bool operator<=(const MoveOnly& other) const { return i_ <= other.i_; }
|
||||
bool operator>(const MoveOnly& other) const { return i_ > other.i_; }
|
||||
bool operator>=(const MoveOnly& other) const { return i_ >= other.i_; }
|
||||
|
||||
private:
|
||||
int i_;
|
||||
};
|
||||
|
||||
struct MoveHelper {
|
||||
MOCK_METHOD1(Call, void(MoveOnly));
|
||||
};
|
||||
|
||||
TEST(ComparisonBaseTest, WorksWithMoveOnly) {
|
||||
MoveOnly m{0};
|
||||
MoveHelper helper;
|
||||
|
||||
EXPECT_CALL(helper, Call(Eq(ByRef(m))));
|
||||
helper.Call(MoveOnly(0));
|
||||
EXPECT_CALL(helper, Call(Ne(ByRef(m))));
|
||||
helper.Call(MoveOnly(1));
|
||||
EXPECT_CALL(helper, Call(Le(ByRef(m))));
|
||||
helper.Call(MoveOnly(0));
|
||||
EXPECT_CALL(helper, Call(Lt(ByRef(m))));
|
||||
helper.Call(MoveOnly(-1));
|
||||
EXPECT_CALL(helper, Call(Ge(ByRef(m))));
|
||||
helper.Call(MoveOnly(0));
|
||||
EXPECT_CALL(helper, Call(Gt(ByRef(m))));
|
||||
helper.Call(MoveOnly(1));
|
||||
}
|
||||
|
||||
// Tests that IsNull() matches any NULL pointer of any type.
|
||||
TEST(IsNullTest, MatchesNullPointer) {
|
||||
Matcher<int*> m1 = IsNull();
|
||||
|
@ -1448,6 +1489,11 @@ TEST(KeyTest, MatchesCorrectly) {
|
|||
EXPECT_THAT(p, Not(Key(Lt(25))));
|
||||
}
|
||||
|
||||
TEST(KeyTest, WorksWithMoveOnly) {
|
||||
pair<std::unique_ptr<int>, std::unique_ptr<int>> p;
|
||||
EXPECT_THAT(p, Key(Eq(nullptr)));
|
||||
}
|
||||
|
||||
template <size_t I>
|
||||
struct Tag {};
|
||||
|
||||
|
@ -1591,6 +1637,12 @@ TEST(PairTest, MatchesCorrectly) {
|
|||
EXPECT_THAT(p, Not(Pair(Lt(13), HasSubstr("a"))));
|
||||
}
|
||||
|
||||
TEST(PairTest, WorksWithMoveOnly) {
|
||||
pair<std::unique_ptr<int>, std::unique_ptr<int>> p;
|
||||
p.second.reset(new int(7));
|
||||
EXPECT_THAT(p, Pair(Eq(nullptr), Ne(nullptr)));
|
||||
}
|
||||
|
||||
TEST(PairTest, SafelyCastsInnerMatchers) {
|
||||
Matcher<int> is_positive = Gt(0);
|
||||
Matcher<int> is_negative = Lt(0);
|
||||
|
@ -2244,6 +2296,15 @@ TEST(Ne2Test, CanDescribeSelf) {
|
|||
EXPECT_EQ("are an unequal pair", Describe(m));
|
||||
}
|
||||
|
||||
TEST(PairMatchBaseTest, WorksWithMoveOnly) {
|
||||
using Pointers = std::tuple<std::unique_ptr<int>, std::unique_ptr<int>>;
|
||||
Matcher<Pointers> matcher = Eq();
|
||||
Pointers pointers;
|
||||
// Tested values don't matter; the point is that matcher does not copy the
|
||||
// matched values.
|
||||
EXPECT_TRUE(matcher.Matches(pointers));
|
||||
}
|
||||
|
||||
// Tests that FloatEq() matches a 2-tuple where
|
||||
// FloatEq(first field) matches the second field.
|
||||
TEST(FloatEq2Test, MatchesEqualArguments) {
|
||||
|
@ -6566,49 +6627,53 @@ TEST(UnorderedPointwiseTest, WorksWithMoveOnly) {
|
|||
|
||||
// Sample optional type implementation with minimal requirements for use with
|
||||
// Optional matcher.
|
||||
class SampleOptionalInt {
|
||||
template <typename T>
|
||||
class SampleOptional {
|
||||
public:
|
||||
typedef int value_type;
|
||||
explicit SampleOptionalInt(int value) : value_(value), has_value_(true) {}
|
||||
SampleOptionalInt() : value_(0), has_value_(false) {}
|
||||
operator bool() const {
|
||||
return has_value_;
|
||||
}
|
||||
const int& operator*() const {
|
||||
return value_;
|
||||
}
|
||||
using value_type = T;
|
||||
explicit SampleOptional(T value)
|
||||
: value_(std::move(value)), has_value_(true) {}
|
||||
SampleOptional() : value_(), has_value_(false) {}
|
||||
operator bool() const { return has_value_; }
|
||||
const T& operator*() const { return value_; }
|
||||
|
||||
private:
|
||||
int value_;
|
||||
T value_;
|
||||
bool has_value_;
|
||||
};
|
||||
|
||||
TEST(OptionalTest, DescribesSelf) {
|
||||
const Matcher<SampleOptionalInt> m = Optional(Eq(1));
|
||||
const Matcher<SampleOptional<int>> m = Optional(Eq(1));
|
||||
EXPECT_EQ("value is equal to 1", Describe(m));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, ExplainsSelf) {
|
||||
const Matcher<SampleOptionalInt> m = Optional(Eq(1));
|
||||
EXPECT_EQ("whose value 1 matches", Explain(m, SampleOptionalInt(1)));
|
||||
EXPECT_EQ("whose value 2 doesn't match", Explain(m, SampleOptionalInt(2)));
|
||||
const Matcher<SampleOptional<int>> m = Optional(Eq(1));
|
||||
EXPECT_EQ("whose value 1 matches", Explain(m, SampleOptional<int>(1)));
|
||||
EXPECT_EQ("whose value 2 doesn't match", Explain(m, SampleOptional<int>(2)));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, MatchesNonEmptyOptional) {
|
||||
const Matcher<SampleOptionalInt> m1 = Optional(1);
|
||||
const Matcher<SampleOptionalInt> m2 = Optional(Eq(2));
|
||||
const Matcher<SampleOptionalInt> m3 = Optional(Lt(3));
|
||||
SampleOptionalInt opt(1);
|
||||
const Matcher<SampleOptional<int>> m1 = Optional(1);
|
||||
const Matcher<SampleOptional<int>> m2 = Optional(Eq(2));
|
||||
const Matcher<SampleOptional<int>> m3 = Optional(Lt(3));
|
||||
SampleOptional<int> opt(1);
|
||||
EXPECT_TRUE(m1.Matches(opt));
|
||||
EXPECT_FALSE(m2.Matches(opt));
|
||||
EXPECT_TRUE(m3.Matches(opt));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, DoesNotMatchNullopt) {
|
||||
const Matcher<SampleOptionalInt> m = Optional(1);
|
||||
SampleOptionalInt empty;
|
||||
const Matcher<SampleOptional<int>> m = Optional(1);
|
||||
SampleOptional<int> empty;
|
||||
EXPECT_FALSE(m.Matches(empty));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, WorksWithMoveOnly) {
|
||||
Matcher<SampleOptional<std::unique_ptr<int>>> m = Optional(Eq(nullptr));
|
||||
EXPECT_TRUE(m.Matches(SampleOptional<std::unique_ptr<int>>(nullptr)));
|
||||
}
|
||||
|
||||
class SampleVariantIntString {
|
||||
public:
|
||||
SampleVariantIntString(int i) : i_(i), has_int_(true) {}
|
||||
|
|
|
@ -555,13 +555,12 @@ class PolymorphicMatcher {
|
|||
Impl impl_;
|
||||
};
|
||||
|
||||
// Creates a matcher from its implementation. This is easier to use
|
||||
// than the Matcher<T> constructor as it doesn't require you to
|
||||
// explicitly write the template argument, e.g.
|
||||
// Creates a matcher from its implementation.
|
||||
// DEPRECATED: Especially in the generic code, prefer:
|
||||
// Matcher<T>(new MyMatcherImpl<const T&>(...));
|
||||
//
|
||||
// MakeMatcher(foo);
|
||||
// vs
|
||||
// Matcher<const string&>(foo);
|
||||
// MakeMatcher may create a Matcher that accepts its argument by value, which
|
||||
// leads to unnecessary copies & lack of support for non-copyable types.
|
||||
template <typename T>
|
||||
inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
|
||||
return Matcher<T>(impl);
|
||||
|
@ -596,7 +595,7 @@ class ComparisonBase {
|
|||
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
|
||||
template <typename Lhs>
|
||||
operator Matcher<Lhs>() const {
|
||||
return MakeMatcher(new Impl<Lhs>(rhs_));
|
||||
return Matcher<Lhs>(new Impl<const Lhs&>(rhs_));
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue
Block a user