From 9acd065a905a145eaa0a5ccbc43d7fbfd1079faf Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Sat, 12 Jan 2019 15:41:51 -0500 Subject: Googletest export Add move-only argument support to almost all remaining matchers. PiperOrigin-RevId: 229030728 --- googlemock/include/gmock/gmock-matchers.h | 12 ++-- googlemock/test/gmock-matchers_test.cc | 107 ++++++++++++++++++++++++------ googletest/include/gtest/gtest-matchers.h | 13 ++-- 3 files changed, 98 insertions(+), 34 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 56804f3..2cb7028 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -900,7 +900,7 @@ class PairMatchBase { public: template operator Matcher<::std::tuple>() const { - return MakeMatcher(new Impl<::std::tuple>); + return Matcher<::std::tuple>(new Impl&>); } template operator Matcher&>() const { @@ -2535,7 +2535,8 @@ class KeyMatcher { template operator Matcher() const { - return MakeMatcher(new KeyMatcherImpl(matcher_for_key_)); + return Matcher( + new KeyMatcherImpl(matcher_for_key_)); } private: @@ -2640,9 +2641,8 @@ class PairMatcher { template operator Matcher () const { - return MakeMatcher( - new PairMatcherImpl( - first_matcher_, second_matcher_)); + return Matcher( + new PairMatcherImpl(first_matcher_, second_matcher_)); } private: @@ -3205,7 +3205,7 @@ class OptionalMatcher { template operator Matcher() const { - return MakeMatcher(new Impl(value_matcher_)); + return Matcher(new Impl(value_matcher_)); } template diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 26b0d9d..932229e 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -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 m1 = IsNull(); @@ -1448,6 +1489,11 @@ TEST(KeyTest, MatchesCorrectly) { EXPECT_THAT(p, Not(Key(Lt(25)))); } +TEST(KeyTest, WorksWithMoveOnly) { + pair, std::unique_ptr> p; + EXPECT_THAT(p, Key(Eq(nullptr))); +} + template 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> p; + p.second.reset(new int(7)); + EXPECT_THAT(p, Pair(Eq(nullptr), Ne(nullptr))); +} + TEST(PairTest, SafelyCastsInnerMatchers) { Matcher is_positive = Gt(0); Matcher 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>; + Matcher 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 +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 m = Optional(Eq(1)); + const Matcher> m = Optional(Eq(1)); EXPECT_EQ("value is equal to 1", Describe(m)); } TEST(OptionalTest, ExplainsSelf) { - const Matcher 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> m = Optional(Eq(1)); + EXPECT_EQ("whose value 1 matches", Explain(m, SampleOptional(1))); + EXPECT_EQ("whose value 2 doesn't match", Explain(m, SampleOptional(2))); } TEST(OptionalTest, MatchesNonEmptyOptional) { - const Matcher m1 = Optional(1); - const Matcher m2 = Optional(Eq(2)); - const Matcher m3 = Optional(Lt(3)); - SampleOptionalInt opt(1); + const Matcher> m1 = Optional(1); + const Matcher> m2 = Optional(Eq(2)); + const Matcher> m3 = Optional(Lt(3)); + SampleOptional opt(1); EXPECT_TRUE(m1.Matches(opt)); EXPECT_FALSE(m2.Matches(opt)); EXPECT_TRUE(m3.Matches(opt)); } TEST(OptionalTest, DoesNotMatchNullopt) { - const Matcher m = Optional(1); - SampleOptionalInt empty; + const Matcher> m = Optional(1); + SampleOptional empty; EXPECT_FALSE(m.Matches(empty)); } +TEST(OptionalTest, WorksWithMoveOnly) { + Matcher>> m = Optional(Eq(nullptr)); + EXPECT_TRUE(m.Matches(SampleOptional>(nullptr))); +} + class SampleVariantIntString { public: SampleVariantIntString(int i) : i_(i), has_int_(true) {} diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h index 128fdb2..9a8841b 100644 --- a/googletest/include/gtest/gtest-matchers.h +++ b/googletest/include/gtest/gtest-matchers.h @@ -555,13 +555,12 @@ class PolymorphicMatcher { Impl impl_; }; -// Creates a matcher from its implementation. This is easier to use -// than the Matcher 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(new MyMatcherImpl(...)); // -// MakeMatcher(foo); -// vs -// Matcher(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 inline Matcher MakeMatcher(const MatcherInterface* impl) { return Matcher(impl); @@ -596,7 +595,7 @@ class ComparisonBase { explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} template operator Matcher() const { - return MakeMatcher(new Impl(rhs_)); + return Matcher(new Impl(rhs_)); } private: -- cgit v0.12