From a42cdf2abdc0ab7ddfbafc098cafdd6152ae1b70 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 3 Dec 2018 10:48:03 -0500 Subject: Googletest export Replace pump'd Args() matcher with variadic templates. PiperOrigin-RevId: 223794430 --- .../include/gmock/gmock-generated-matchers.h | 337 --------------------- .../include/gmock/gmock-generated-matchers.h.pump | 163 ---------- googlemock/include/gmock/gmock-matchers.h | 84 +++++ googlemock/test/gmock-generated-matchers_test.cc | 152 ---------- googlemock/test/gmock-matchers_test.cc | 152 +++++++++- 5 files changed, 233 insertions(+), 655 deletions(-) diff --git a/googlemock/include/gmock/gmock-generated-matchers.h b/googlemock/include/gmock/gmock-generated-matchers.h index 1a88c71..b77b3f1 100644 --- a/googlemock/include/gmock/gmock-generated-matchers.h +++ b/googlemock/include/gmock/gmock-generated-matchers.h @@ -47,343 +47,6 @@ #include #include "gmock/gmock-matchers.h" -namespace testing { -namespace internal { - -// The type of the i-th (0-based) field of Tuple. -#define GMOCK_FIELD_TYPE_(Tuple, i) \ - typename ::std::tuple_element::type - -// TupleFields is for selecting fields from a -// tuple of type Tuple. It has two members: -// -// type: a tuple type whose i-th field is the ki-th field of Tuple. -// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple. -// -// For example, in class TupleFields, 2, 0>, -// we have: -// -// type is std::tuple, and -// GetSelectedFields(std::make_tuple(true, 'a', 42)) is (42, true). - -template -class TupleFields; - -// This generic version is used when there are 10 selectors. -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t), std::get(t), - std::get(t), std::get(t), std::get(t), std::get(t), - std::get(t), std::get(t), std::get(t)); - } -}; - -// The following specialization is used for 0 ~ 9 selectors. - -template -class TupleFields { - public: - typedef ::std::tuple<> type; - static type GetSelectedFields(const Tuple& /* t */) { - return type(); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t), std::get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t), std::get(t), - std::get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t), std::get(t), - std::get(t), std::get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t), std::get(t), - std::get(t), std::get(t), std::get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t), std::get(t), - std::get(t), std::get(t), std::get(t), std::get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t), std::get(t), - std::get(t), std::get(t), std::get(t), std::get(t), - std::get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::std::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(std::get(t), std::get(t), std::get(t), - std::get(t), std::get(t), std::get(t), std::get(t), - std::get(t), std::get(t)); - } -}; - -#undef GMOCK_FIELD_TYPE_ - -// Implements the Args() matcher. -template -class ArgsMatcherImpl : public MatcherInterface { - public: - // ArgsTuple may have top-level const or reference modifiers. - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple; - typedef typename internal::TupleFields::type SelectedArgs; - typedef Matcher MonomorphicInnerMatcher; - - template - explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) - : inner_matcher_(SafeMatcherCast(inner_matcher)) {} - - virtual bool MatchAndExplain(ArgsTuple args, - MatchResultListener* listener) const { - const SelectedArgs& selected_args = GetSelectedArgs(args); - if (!listener->IsInterested()) - return inner_matcher_.Matches(selected_args); - - PrintIndices(listener->stream()); - *listener << "are " << PrintToString(selected_args); - - StringMatchResultListener inner_listener; - const bool match = inner_matcher_.MatchAndExplain(selected_args, - &inner_listener); - PrintIfNotEmpty(inner_listener.str(), listener->stream()); - return match; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeNegationTo(os); - } - - private: - static SelectedArgs GetSelectedArgs(ArgsTuple args) { - return TupleFields::GetSelectedFields(args); - } - - // Prints the indices of the selected fields. - static void PrintIndices(::std::ostream* os) { - *os << "whose fields ("; - const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 }; - for (int i = 0; i < 10; i++) { - if (indices[i] < 0) - break; - - if (i >= 1) - *os << ", "; - - *os << "#" << indices[i]; - } - *os << ") "; - } - - const MonomorphicInnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl); -}; - -template -class ArgsMatcher { - public: - explicit ArgsMatcher(const InnerMatcher& inner_matcher) - : inner_matcher_(inner_matcher) {} - - template - operator Matcher() const { - return MakeMatcher(new ArgsMatcherImpl(inner_matcher_)); - } - - private: - const InnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcher); -}; - -} // namespace internal - -// Args(a_matcher) matches a tuple if the selected -// fields of it matches a_matcher. C++ doesn't support default -// arguments for function templates, so we have to overload it. -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - - -} // namespace testing - - // The MATCHER* family of macros can be used in a namespace scope to // define custom matchers easily. // diff --git a/googlemock/include/gmock/gmock-generated-matchers.h.pump b/googlemock/include/gmock/gmock-generated-matchers.h.pump index 322e0ff..8be4869 100644 --- a/googlemock/include/gmock/gmock-generated-matchers.h.pump +++ b/googlemock/include/gmock/gmock-generated-matchers.h.pump @@ -49,169 +49,6 @@ $$ }} This line fixes auto-indentation of the following code in Emacs. #include #include "gmock/gmock-matchers.h" -namespace testing { -namespace internal { - -$range i 0..n-1 - -// The type of the i-th (0-based) field of Tuple. -#define GMOCK_FIELD_TYPE_(Tuple, i) \ - typename ::std::tuple_element::type - -// TupleFields is for selecting fields from a -// tuple of type Tuple. It has two members: -// -// type: a tuple type whose i-th field is the ki-th field of Tuple. -// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple. -// -// For example, in class TupleFields, 2, 0>, -// we have: -// -// type is std::tuple, and -// GetSelectedFields(std::make_tuple(true, 'a', 42)) is (42, true). - -template -class TupleFields; - -// This generic version is used when there are $n selectors. -template -class TupleFields { - public: - typedef ::std::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type; - static type GetSelectedFields(const Tuple& t) { - return type($for i, [[std::get(t)]]); - } -}; - -// The following specialization is used for 0 ~ $(n-1) selectors. - -$for i [[ -$$ }}} -$range j 0..i-1 -$range k 0..n-1 - -template -class TupleFields { - public: - typedef ::std::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type; - static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) { - return type($for j, [[std::get(t)]]); - } -}; - -]] - -#undef GMOCK_FIELD_TYPE_ - -// Implements the Args() matcher. - -$var ks = [[$for i, [[k$i]]]] -template -class ArgsMatcherImpl : public MatcherInterface { - public: - // ArgsTuple may have top-level const or reference modifiers. - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple; - typedef typename internal::TupleFields::type SelectedArgs; - typedef Matcher MonomorphicInnerMatcher; - - template - explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) - : inner_matcher_(SafeMatcherCast(inner_matcher)) {} - - virtual bool MatchAndExplain(ArgsTuple args, - MatchResultListener* listener) const { - const SelectedArgs& selected_args = GetSelectedArgs(args); - if (!listener->IsInterested()) - return inner_matcher_.Matches(selected_args); - - PrintIndices(listener->stream()); - *listener << "are " << PrintToString(selected_args); - - StringMatchResultListener inner_listener; - const bool match = inner_matcher_.MatchAndExplain(selected_args, - &inner_listener); - PrintIfNotEmpty(inner_listener.str(), listener->stream()); - return match; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeNegationTo(os); - } - - private: - static SelectedArgs GetSelectedArgs(ArgsTuple args) { - return TupleFields::GetSelectedFields(args); - } - - // Prints the indices of the selected fields. - static void PrintIndices(::std::ostream* os) { - *os << "whose fields ("; - const int indices[$n] = { $ks }; - for (int i = 0; i < $n; i++) { - if (indices[i] < 0) - break; - - if (i >= 1) - *os << ", "; - - *os << "#" << indices[i]; - } - *os << ") "; - } - - const MonomorphicInnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl); -}; - -template -class ArgsMatcher { - public: - explicit ArgsMatcher(const InnerMatcher& inner_matcher) - : inner_matcher_(inner_matcher) {} - - template - operator Matcher() const { - return MakeMatcher(new ArgsMatcherImpl(inner_matcher_)); - } - - private: - const InnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcher); -}; - -} // namespace internal - -// Args(a_matcher) matches a tuple if the selected -// fields of it matches a_matcher. C++ doesn't support default -// arguments for function templates, so we have to overload it. - -$range i 0..n -$for i [[ -$range j 1..i -template <$for j [[int k$j, ]]typename InnerMatcher> -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - - -]] - -} // namespace testing -$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not -$$ // show up in the generated code. - - // The MATCHER* family of macros can be used in a namespace scope to // define custom matchers easily. // diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index ba057de..69dfd83 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -3424,6 +3424,80 @@ class AnyCastMatcher { }; } // namespace any_cast_matcher + +// Implements the Args() matcher. +template +class ArgsMatcherImpl : public MatcherInterface { + public: + using RawArgsTuple = typename std::decay::type; + using SelectedArgs = + std::tuple::type...>; + using MonomorphicInnerMatcher = Matcher; + + template + explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) + : inner_matcher_(SafeMatcherCast(inner_matcher)) {} + + bool MatchAndExplain(ArgsTuple args, + MatchResultListener* listener) const override { + // Workaround spurious C4100 on MSVC<=15.7 when k is empty. + (void)args; + const SelectedArgs& selected_args = + std::forward_as_tuple(std::get(args)...); + if (!listener->IsInterested()) return inner_matcher_.Matches(selected_args); + + PrintIndices(listener->stream()); + *listener << "are " << PrintToString(selected_args); + + StringMatchResultListener inner_listener; + const bool match = + inner_matcher_.MatchAndExplain(selected_args, &inner_listener); + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return match; + } + + void DescribeTo(::std::ostream* os) const override { + *os << "are a tuple "; + PrintIndices(os); + inner_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "are a tuple "; + PrintIndices(os); + inner_matcher_.DescribeNegationTo(os); + } + + private: + // Prints the indices of the selected fields. + static void PrintIndices(::std::ostream* os) { + *os << "whose fields ("; + const char* sep = ""; + // Workaround spurious C4189 on MSVC<=15.7 when k is empty. + (void)sep; + const char* dummy[] = {"", (*os << sep << "#" << k, sep = ", ")...}; + (void)dummy; + *os << ") "; + } + + MonomorphicInnerMatcher inner_matcher_; +}; + +template +class ArgsMatcher { + public: + explicit ArgsMatcher(InnerMatcher inner_matcher) + : inner_matcher_(std::move(inner_matcher)) {} + + template + operator Matcher() const { // NOLINT + return MakeMatcher(new ArgsMatcherImpl(inner_matcher_)); + } + + private: + InnerMatcher inner_matcher_; +}; + } // namespace internal // ElementsAreArray(iterator_first, iterator_last) @@ -4371,6 +4445,16 @@ internal::AnyOfMatcher::type...> AnyOf( matchers...); } +// Args(a_matcher) matches a tuple if the selected +// fields of it matches a_matcher. C++ doesn't support default +// arguments for function templates, so we have to overload it. +template +internal::ArgsMatcher::type, k...> Args( + InnerMatcher&& matcher) { + return internal::ArgsMatcher::type, k...>( + std::forward(matcher)); +} + // AllArgs(m) is a synonym of m. This is useful in // // EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq())); diff --git a/googlemock/test/gmock-generated-matchers_test.cc b/googlemock/test/gmock-generated-matchers_test.cc index fdbfb54..c66f675 100644 --- a/googlemock/test/gmock-generated-matchers_test.cc +++ b/googlemock/test/gmock-generated-matchers_test.cc @@ -112,154 +112,6 @@ std::string Explain(const MatcherType& m, const Value& x) { return ss.str(); } -// Tests Args(m). - -TEST(ArgsTest, AcceptsZeroTemplateArg) { - const std::tuple t(5, true); - EXPECT_THAT(t, Args<>(Eq(std::tuple<>()))); - EXPECT_THAT(t, Not(Args<>(Ne(std::tuple<>())))); -} - -TEST(ArgsTest, AcceptsOneTemplateArg) { - const std::tuple t(5, true); - EXPECT_THAT(t, Args<0>(Eq(std::make_tuple(5)))); - EXPECT_THAT(t, Args<1>(Eq(std::make_tuple(true)))); - EXPECT_THAT(t, Not(Args<1>(Eq(std::make_tuple(false))))); -} - -TEST(ArgsTest, AcceptsTwoTemplateArgs) { - const std::tuple t(4, 5, 6L); // NOLINT - - EXPECT_THAT(t, (Args<0, 1>(Lt()))); - EXPECT_THAT(t, (Args<1, 2>(Lt()))); - EXPECT_THAT(t, Not(Args<0, 2>(Gt()))); -} - -TEST(ArgsTest, AcceptsRepeatedTemplateArgs) { - const std::tuple t(4, 5, 6L); // NOLINT - EXPECT_THAT(t, (Args<0, 0>(Eq()))); - EXPECT_THAT(t, Not(Args<1, 1>(Ne()))); -} - -TEST(ArgsTest, AcceptsDecreasingTemplateArgs) { - const std::tuple t(4, 5, 6L); // NOLINT - EXPECT_THAT(t, (Args<2, 0>(Gt()))); - EXPECT_THAT(t, Not(Args<2, 1>(Lt()))); -} - -// The MATCHER*() macros trigger warning C4100 (unreferenced formal -// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in -// the macro definition, as the warnings are generated when the macro -// is expanded and macro expansion cannot contain #pragma. Therefore -// we suppress them here. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) -#endif - -MATCHER(SumIsZero, "") { - return std::get<0>(arg) + std::get<1>(arg) + std::get<2>(arg) == 0; -} - -TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) { - EXPECT_THAT(std::make_tuple(-1, 2), (Args<0, 0, 1>(SumIsZero()))); - EXPECT_THAT(std::make_tuple(1, 2), Not(Args<0, 0, 1>(SumIsZero()))); -} - -TEST(ArgsTest, CanBeNested) { - const std::tuple t(4, 5, 6L, 6); // NOLINT - EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq())))); - EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt())))); -} - -TEST(ArgsTest, CanMatchTupleByValue) { - typedef std::tuple Tuple3; - const Matcher m = Args<1, 2>(Lt()); - EXPECT_TRUE(m.Matches(Tuple3('a', 1, 2))); - EXPECT_FALSE(m.Matches(Tuple3('b', 2, 2))); -} - -TEST(ArgsTest, CanMatchTupleByReference) { - typedef std::tuple Tuple3; - const Matcher m = Args<0, 1>(Lt()); - EXPECT_TRUE(m.Matches(Tuple3('a', 'b', 2))); - EXPECT_FALSE(m.Matches(Tuple3('b', 'b', 2))); -} - -// Validates that arg is printed as str. -MATCHER_P(PrintsAs, str, "") { - return testing::PrintToString(arg) == str; -} - -TEST(ArgsTest, AcceptsTenTemplateArgs) { - EXPECT_THAT(std::make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), - (Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( - PrintsAs("(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); - EXPECT_THAT(std::make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), - Not(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( - PrintsAs("(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); -} - -TEST(ArgsTest, DescirbesSelfCorrectly) { - const Matcher > m = Args<2, 0>(Lt()); - EXPECT_EQ("are a tuple whose fields (#2, #0) are a pair where " - "the first < the second", - Describe(m)); -} - -TEST(ArgsTest, DescirbesNestedArgsCorrectly) { - const Matcher&> m = - Args<0, 2, 3>(Args<2, 0>(Lt())); - EXPECT_EQ("are a tuple whose fields (#0, #2, #3) are a tuple " - "whose fields (#2, #0) are a pair where the first < the second", - Describe(m)); -} - -TEST(ArgsTest, DescribesNegationCorrectly) { - const Matcher > m = Args<1, 0>(Gt()); - EXPECT_EQ("are a tuple whose fields (#1, #0) aren't a pair " - "where the first > the second", - DescribeNegation(m)); -} - -TEST(ArgsTest, ExplainsMatchResultWithoutInnerExplanation) { - const Matcher > m = Args<1, 2>(Eq()); - EXPECT_EQ("whose fields (#1, #2) are (42, 42)", - Explain(m, std::make_tuple(false, 42, 42))); - EXPECT_EQ("whose fields (#1, #2) are (42, 43)", - Explain(m, std::make_tuple(false, 42, 43))); -} - -// For testing Args<>'s explanation. -class LessThanMatcher : public MatcherInterface > { - public: - virtual void DescribeTo(::std::ostream* os) const {} - - virtual bool MatchAndExplain(std::tuple value, - MatchResultListener* listener) const { - const int diff = std::get<0>(value) - std::get<1>(value); - if (diff > 0) { - *listener << "where the first value is " << diff - << " more than the second"; - } - return diff < 0; - } -}; - -Matcher > LessThan() { - return MakeMatcher(new LessThanMatcher); -} - -TEST(ArgsTest, ExplainsMatchResultWithInnerExplanation) { - const Matcher > m = Args<0, 2>(LessThan()); - EXPECT_EQ( - "whose fields (#0, #2) are ('a' (97, 0x61), 42), " - "where the first value is 55 more than the second", - Explain(m, std::make_tuple('a', 42, 42))); - EXPECT_EQ("whose fields (#0, #2) are ('\\0', 43)", - Explain(m, std::make_tuple('\0', 42, 43))); -} - // For testing ExplainMatchResultTo(). class GreaterThanMatcher : public MatcherInterface { public: @@ -1288,10 +1140,6 @@ TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) { } // namespace adl_test -#ifdef _MSC_VER -# pragma warning(pop) -#endif - #if GTEST_LANG_CXX11 TEST(AllOfTest, WorksOnMoveOnlyType) { diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 347c2c7..cb2d1ae 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -32,6 +32,14 @@ // // This file tests some commonly used argument matchers. +// Silence warning C4244: 'initializing': conversion from 'int' to 'short', +// possible loss of data and C4100, unreferenced local parameter +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4244) +# pragma warning(disable:4100) +#endif + #include "gmock/gmock-matchers.h" #include "gmock/gmock-more-matchers.h" @@ -6748,8 +6756,6 @@ TEST(AnyWithTest, ExplainsSelf) { EXPECT_THAT(Explain(m, SampleAnyType(2)), "whose value 2 doesn't match"); } -#if GTEST_LANG_CXX11 - TEST(PointeeTest, WorksOnMoveOnlyType) { std::unique_ptr p(new int(3)); EXPECT_THAT(p, Pointee(Eq(3))); @@ -6762,7 +6768,147 @@ TEST(NotTest, WorksOnMoveOnlyType) { EXPECT_THAT(p, Not(Pointee(Eq(2)))); } -#endif // GTEST_LANG_CXX11 +// Tests Args(m). + +TEST(ArgsTest, AcceptsZeroTemplateArg) { + const std::tuple t(5, true); + EXPECT_THAT(t, Args<>(Eq(std::tuple<>()))); + EXPECT_THAT(t, Not(Args<>(Ne(std::tuple<>())))); +} + +TEST(ArgsTest, AcceptsOneTemplateArg) { + const std::tuple t(5, true); + EXPECT_THAT(t, Args<0>(Eq(std::make_tuple(5)))); + EXPECT_THAT(t, Args<1>(Eq(std::make_tuple(true)))); + EXPECT_THAT(t, Not(Args<1>(Eq(std::make_tuple(false))))); +} + +TEST(ArgsTest, AcceptsTwoTemplateArgs) { + const std::tuple t(4, 5, 6L); // NOLINT + + EXPECT_THAT(t, (Args<0, 1>(Lt()))); + EXPECT_THAT(t, (Args<1, 2>(Lt()))); + EXPECT_THAT(t, Not(Args<0, 2>(Gt()))); +} + +TEST(ArgsTest, AcceptsRepeatedTemplateArgs) { + const std::tuple t(4, 5, 6L); // NOLINT + EXPECT_THAT(t, (Args<0, 0>(Eq()))); + EXPECT_THAT(t, Not(Args<1, 1>(Ne()))); +} + +TEST(ArgsTest, AcceptsDecreasingTemplateArgs) { + const std::tuple t(4, 5, 6L); // NOLINT + EXPECT_THAT(t, (Args<2, 0>(Gt()))); + EXPECT_THAT(t, Not(Args<2, 1>(Lt()))); +} + +MATCHER(SumIsZero, "") { + return std::get<0>(arg) + std::get<1>(arg) + std::get<2>(arg) == 0; +} + +TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) { + EXPECT_THAT(std::make_tuple(-1, 2), (Args<0, 0, 1>(SumIsZero()))); + EXPECT_THAT(std::make_tuple(1, 2), Not(Args<0, 0, 1>(SumIsZero()))); +} + +TEST(ArgsTest, CanBeNested) { + const std::tuple t(4, 5, 6L, 6); // NOLINT + EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq())))); + EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt())))); +} + +TEST(ArgsTest, CanMatchTupleByValue) { + typedef std::tuple Tuple3; + const Matcher m = Args<1, 2>(Lt()); + EXPECT_TRUE(m.Matches(Tuple3('a', 1, 2))); + EXPECT_FALSE(m.Matches(Tuple3('b', 2, 2))); +} + +TEST(ArgsTest, CanMatchTupleByReference) { + typedef std::tuple Tuple3; + const Matcher m = Args<0, 1>(Lt()); + EXPECT_TRUE(m.Matches(Tuple3('a', 'b', 2))); + EXPECT_FALSE(m.Matches(Tuple3('b', 'b', 2))); +} + +// Validates that arg is printed as str. +MATCHER_P(PrintsAs, str, "") { + return testing::PrintToString(arg) == str; +} + +TEST(ArgsTest, AcceptsTenTemplateArgs) { + EXPECT_THAT(std::make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), + (Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( + PrintsAs("(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); + EXPECT_THAT(std::make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), + Not(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( + PrintsAs("(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); +} + +TEST(ArgsTest, DescirbesSelfCorrectly) { + const Matcher > m = Args<2, 0>(Lt()); + EXPECT_EQ("are a tuple whose fields (#2, #0) are a pair where " + "the first < the second", + Describe(m)); +} + +TEST(ArgsTest, DescirbesNestedArgsCorrectly) { + const Matcher&> m = + Args<0, 2, 3>(Args<2, 0>(Lt())); + EXPECT_EQ("are a tuple whose fields (#0, #2, #3) are a tuple " + "whose fields (#2, #0) are a pair where the first < the second", + Describe(m)); +} + +TEST(ArgsTest, DescribesNegationCorrectly) { + const Matcher > m = Args<1, 0>(Gt()); + EXPECT_EQ("are a tuple whose fields (#1, #0) aren't a pair " + "where the first > the second", + DescribeNegation(m)); +} + +TEST(ArgsTest, ExplainsMatchResultWithoutInnerExplanation) { + const Matcher > m = Args<1, 2>(Eq()); + EXPECT_EQ("whose fields (#1, #2) are (42, 42)", + Explain(m, std::make_tuple(false, 42, 42))); + EXPECT_EQ("whose fields (#1, #2) are (42, 43)", + Explain(m, std::make_tuple(false, 42, 43))); +} + +// For testing Args<>'s explanation. +class LessThanMatcher : public MatcherInterface > { + public: + virtual void DescribeTo(::std::ostream* os) const {} + + virtual bool MatchAndExplain(std::tuple value, + MatchResultListener* listener) const { + const int diff = std::get<0>(value) - std::get<1>(value); + if (diff > 0) { + *listener << "where the first value is " << diff + << " more than the second"; + } + return diff < 0; + } +}; + +Matcher > LessThan() { + return MakeMatcher(new LessThanMatcher); +} + +TEST(ArgsTest, ExplainsMatchResultWithInnerExplanation) { + const Matcher > m = Args<0, 2>(LessThan()); + EXPECT_EQ( + "whose fields (#0, #2) are ('a' (97, 0x61), 42), " + "where the first value is 55 more than the second", + Explain(m, std::make_tuple('a', 42, 42))); + EXPECT_EQ("whose fields (#0, #2) are ('\\0', 43)", + Explain(m, std::make_tuple('\0', 42, 43))); +} } // namespace gmock_matchers_test } // namespace testing + +#ifdef _MSC_VER +# pragma warning(pop) +#endif -- cgit v0.12