From 238e4745c62258ca1d2f3c514789205e8419eeee Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 26 Apr 2022 09:48:24 -0700 Subject: Generalize gmock-matchers_test to handle is_gtest_matcher-style matchers, too. PiperOrigin-RevId: 444586594 Change-Id: I0de9b40b3773e3047a492f050266967ea935ae3e --- googlemock/test/gmock-matchers-arithmetic_test.cc | 8 ++- googlemock/test/gmock-matchers-comparisons_test.cc | 52 ++++++++++++---- googlemock/test/gmock-matchers-containers_test.cc | 52 +++++++++++----- googlemock/test/gmock-matchers-misc_test.cc | 12 +++- googlemock/test/gmock-matchers_test.h | 70 +++++++++++++++++----- 5 files changed, 144 insertions(+), 50 deletions(-) diff --git a/googlemock/test/gmock-matchers-arithmetic_test.cc b/googlemock/test/gmock-matchers-arithmetic_test.cc index ef53baa..a4c1def 100644 --- a/googlemock/test/gmock-matchers-arithmetic_test.cc +++ b/googlemock/test/gmock-matchers-arithmetic_test.cc @@ -429,6 +429,8 @@ void AllOfMatches(int num, const Matcher& m) { EXPECT_TRUE(m.Matches(num + 1)); } +INSTANTIATE_GTEST_MATCHER_TEST_P(AllOfTest); + // Tests that AllOf(m1, ..., mn) matches any value that matches all of // the given matchers. TEST(AllOfTest, MatchesWhenAllMatch) { @@ -552,7 +554,7 @@ TEST(AllOfTest, AllOfMatcherSafelyCastsMonomorphicMatchers) { Matcher m5 = AllOf(greater_than_5, less_than_10, less_than_10); } -TEST(AllOfTest, ExplainsResult) { +TEST_P(AllOfTestP, ExplainsResult) { Matcher m; // Successful match. Both matchers need to explain. The second @@ -616,6 +618,8 @@ static void AnyOfStringMatches(int num, const Matcher& m) { EXPECT_FALSE(m.Matches(std::to_string(num + 1))); } +INSTANTIATE_GTEST_MATCHER_TEST_P(AnyOfTest); + // Tests that AnyOf(m1, ..., mn) matches any value that matches at // least one of the given matchers. TEST(AnyOfTest, MatchesWhenAnyMatches) { @@ -766,7 +770,7 @@ TEST(AnyOfTest, AnyOfMatcherSafelyCastsMonomorphicMatchers) { Matcher m5 = AnyOf(greater_than_5, less_than_10, less_than_10); } -TEST(AnyOfTest, ExplainsResult) { +TEST_P(AnyOfTestP, ExplainsResult) { Matcher m; // Failed match. Both matchers need to explain. The second diff --git a/googlemock/test/gmock-matchers-comparisons_test.cc b/googlemock/test/gmock-matchers-comparisons_test.cc index 63af04e..eb8f3f6 100644 --- a/googlemock/test/gmock-matchers-comparisons_test.cc +++ b/googlemock/test/gmock-matchers-comparisons_test.cc @@ -45,7 +45,9 @@ namespace testing { namespace gmock_matchers_test { namespace { -TEST(MonotonicMatcherTest, IsPrintable) { +INSTANTIATE_GTEST_MATCHER_TEST_P(MonotonicMatcherTest); + +TEST_P(MonotonicMatcherTestP, IsPrintable) { stringstream ss; ss << GreaterThan(5); EXPECT_EQ("is > 5", ss.str()); @@ -130,6 +132,8 @@ TEST(MatcherInterfaceTest, CanBeImplementedUsingNewAPI) { EXPECT_EQ("value % 2 == 1", Explain(m, 3)); } +INSTANTIATE_GTEST_MATCHER_TEST_P(MatcherTest); + // Tests default-constructing a matcher. TEST(MatcherTest, CanBeDefaultConstructed) { Matcher m; } @@ -192,7 +196,7 @@ TEST(MatcherTest, CanDescribeItself) { } // Tests Matcher::MatchAndExplain(). -TEST(MatcherTest, MatchAndExplain) { +TEST_P(MatcherTestP, MatchAndExplain) { Matcher m = GreaterThan(0); StringMatchResultListener listener1; EXPECT_TRUE(m.MatchAndExplain(42, &listener1)); @@ -376,11 +380,18 @@ TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingNewAPI) { EXPECT_EQ("% 2 == 0", Explain(m2, '\x42')); } +INSTANTIATE_GTEST_MATCHER_TEST_P(MatcherCastTest); + // Tests that MatcherCast(m) works when m is a polymorphic matcher. -TEST(MatcherCastTest, FromPolymorphicMatcher) { - Matcher m = MatcherCast(Eq(5)); - EXPECT_TRUE(m.Matches(5)); - EXPECT_FALSE(m.Matches(6)); +TEST_P(MatcherCastTestP, FromPolymorphicMatcher) { + Matcher m; + if (use_gtest_matcher_) { + m = MatcherCast(GtestGreaterThan(int64_t{5})); + } else { + m = MatcherCast(Gt(int64_t{5})); + } + EXPECT_TRUE(m.Matches(6)); + EXPECT_FALSE(m.Matches(4)); } // For testing casting matchers between compatible types. @@ -591,10 +602,17 @@ class Derived : public Base { class OtherDerived : public Base {}; +INSTANTIATE_GTEST_MATCHER_TEST_P(SafeMatcherCastTest); + // Tests that SafeMatcherCast(m) works when m is a polymorphic matcher. -TEST(SafeMatcherCastTest, FromPolymorphicMatcher) { - Matcher m2 = SafeMatcherCast(Eq(32)); - EXPECT_TRUE(m2.Matches(' ')); +TEST_P(SafeMatcherCastTestP, FromPolymorphicMatcher) { + Matcher m2; + if (use_gtest_matcher_) { + m2 = SafeMatcherCast(GtestGreaterThan(32)); + } else { + m2 = SafeMatcherCast(Gt(32)); + } + EXPECT_TRUE(m2.Matches('A')); EXPECT_FALSE(m2.Matches('\n')); } @@ -1319,13 +1337,15 @@ TEST(HasSubstrTest, CanDescribeSelf) { EXPECT_EQ("has substring \"foo\\n\\\"\"", Describe(m)); } +INSTANTIATE_GTEST_MATCHER_TEST_P(KeyTest); + TEST(KeyTest, CanDescribeSelf) { Matcher&> m = Key("foo"); EXPECT_EQ("has a key that is equal to \"foo\"", Describe(m)); EXPECT_EQ("doesn't have a key that is equal to \"foo\"", DescribeNegation(m)); } -TEST(KeyTest, ExplainsResult) { +TEST_P(KeyTestP, ExplainsResult) { Matcher> m = Key(GreaterThan(10)); EXPECT_EQ("whose first field is a value which is 5 less than 10", Explain(m, make_pair(5, true))); @@ -1346,6 +1366,8 @@ TEST(KeyTest, WorksWithMoveOnly) { EXPECT_THAT(p, Key(Eq(nullptr))); } +INSTANTIATE_GTEST_MATCHER_TEST_P(PairTest); + template struct Tag {}; @@ -1434,7 +1456,7 @@ TEST(PairTest, CanDescribeSelf) { DescribeNegation(m2)); } -TEST(PairTest, CanExplainMatchResultTo) { +TEST_P(PairTestP, CanExplainMatchResultTo) { // If neither field matches, Pair() should explain about the first // field. const Matcher> m = Pair(GreaterThan(0), GreaterThan(0)); @@ -1522,6 +1544,8 @@ TEST(PairTest, InsideContainsUsingMap) { EXPECT_THAT(container, Not(Contains(Pair(3, _)))); } +INSTANTIATE_GTEST_MATCHER_TEST_P(FieldsAreTest); + TEST(FieldsAreTest, MatchesCorrectly) { std::tuple p(25, "foo", .5); @@ -1547,7 +1571,7 @@ TEST(FieldsAreTest, CanDescribeSelf) { DescribeNegation(m1)); } -TEST(FieldsAreTest, CanExplainMatchResultTo) { +TEST_P(FieldsAreTestP, CanExplainMatchResultTo) { // The first one that fails is the one that gives the error. Matcher> m = FieldsAre(GreaterThan(0), GreaterThan(0), GreaterThan(0)); @@ -2261,7 +2285,9 @@ TEST(ExplainMatchResultTest, AllOf_True_True_2) { EXPECT_EQ("", Explain(m, 2)); } -TEST(ExplainmatcherResultTest, MonomorphicMatcher) { +INSTANTIATE_GTEST_MATCHER_TEST_P(ExplainmatcherResultTest); + +TEST_P(ExplainmatcherResultTestP, MonomorphicMatcher) { const Matcher m = GreaterThan(5); EXPECT_EQ("which is 1 more than 5", Explain(m, 6)); } diff --git a/googlemock/test/gmock-matchers-containers_test.cc b/googlemock/test/gmock-matchers-containers_test.cc index be74dd7..f50159f 100644 --- a/googlemock/test/gmock-matchers-containers_test.cc +++ b/googlemock/test/gmock-matchers-containers_test.cc @@ -65,6 +65,8 @@ TEST(ContainsTest, WorksWithMoveOnly) { helper.Call(MakeUniquePtrs({1, 2})); } +INSTANTIATE_GTEST_MATCHER_TEST_P(ElementsAreTest); + // Tests the variadic version of the ElementsAreMatcher TEST(ElementsAreTest, HugeMatcher) { vector test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; @@ -280,6 +282,8 @@ class ConstPropagatingPtr { T* val_; }; +INSTANTIATE_GTEST_MATCHER_TEST_P(PointeeTest); + TEST(PointeeTest, WorksWithConstPropagatingPointers) { const Matcher> m = Pointee(Lt(5)); int three = 3; @@ -314,7 +318,7 @@ TEST(PointeeTest, CanDescribeSelf) { EXPECT_EQ("does not point to a value that is > 3", DescribeNegation(m)); } -TEST(PointeeTest, CanExplainMatchResult) { +TEST_P(PointeeTestP, CanExplainMatchResult) { const Matcher m = Pointee(StartsWith("Hi")); EXPECT_EQ("", Explain(m, static_cast(nullptr))); @@ -370,6 +374,8 @@ struct DerivedStruct : public AStruct { char ch; }; +INSTANTIATE_GTEST_MATCHER_TEST_P(FieldTest); + // Tests that Field(&Foo::field, ...) works when field is non-const. TEST(FieldTest, WorksForNonConstField) { Matcher m = Field(&AStruct::x, Ge(0)); @@ -476,7 +482,7 @@ TEST(FieldTest, CanDescribeSelfWithFieldName) { } // Tests that Field() can explain the match result. -TEST(FieldTest, CanExplainMatchResult) { +TEST_P(FieldTestP, CanExplainMatchResult) { Matcher m = Field(&AStruct::x, Ge(0)); AStruct a; @@ -489,7 +495,7 @@ TEST(FieldTest, CanExplainMatchResult) { Explain(m, a)); } -TEST(FieldTest, CanExplainMatchResultWithFieldName) { +TEST_P(FieldTestP, CanExplainMatchResultWithFieldName) { Matcher m = Field("field_name", &AStruct::x, Ge(0)); AStruct a; @@ -502,6 +508,8 @@ TEST(FieldTest, CanExplainMatchResultWithFieldName) { Explain(m, a)); } +INSTANTIATE_GTEST_MATCHER_TEST_P(FieldForPointerTest); + // Tests that Field() works when the argument is a pointer to const. TEST(FieldForPointerTest, WorksForPointerToConst) { Matcher m = Field(&AStruct::x, Ge(0)); @@ -568,7 +576,7 @@ TEST(FieldForPointerTest, CanDescribeSelfWithFieldName) { } // Tests that Field() can explain the result of matching a pointer. -TEST(FieldForPointerTest, CanExplainMatchResult) { +TEST_P(FieldForPointerTestP, CanExplainMatchResult) { Matcher m = Field(&AStruct::x, Ge(0)); AStruct a; @@ -583,7 +591,7 @@ TEST(FieldForPointerTest, CanExplainMatchResult) { Explain(m, &a)); } -TEST(FieldForPointerTest, CanExplainMatchResultWithFieldName) { +TEST_P(FieldForPointerTestP, CanExplainMatchResultWithFieldName) { Matcher m = Field("field_name", &AStruct::x, Ge(0)); AStruct a; @@ -637,6 +645,8 @@ class DerivedClass : public AClass { int k_; }; +INSTANTIATE_GTEST_MATCHER_TEST_P(PropertyTest); + // Tests that Property(&Foo::property, ...) works when property() // returns a non-reference. TEST(PropertyTest, WorksForNonReferenceProperty) { @@ -763,7 +773,7 @@ TEST(PropertyTest, CanDescribeSelfWithPropertyName) { } // Tests that Property() can explain the match result. -TEST(PropertyTest, CanExplainMatchResult) { +TEST_P(PropertyTestP, CanExplainMatchResult) { Matcher m = Property(&AClass::n, Ge(0)); AClass a; @@ -776,7 +786,7 @@ TEST(PropertyTest, CanExplainMatchResult) { Explain(m, a)); } -TEST(PropertyTest, CanExplainMatchResultWithPropertyName) { +TEST_P(PropertyTestP, CanExplainMatchResultWithPropertyName) { Matcher m = Property("fancy_name", &AClass::n, Ge(0)); AClass a; @@ -789,6 +799,8 @@ TEST(PropertyTest, CanExplainMatchResultWithPropertyName) { Explain(m, a)); } +INSTANTIATE_GTEST_MATCHER_TEST_P(PropertyForPointerTest); + // Tests that Property() works when the argument is a pointer to const. TEST(PropertyForPointerTest, WorksForPointerToConst) { Matcher m = Property(&AClass::n, Ge(0)); @@ -865,7 +877,7 @@ TEST(PropertyForPointerTest, CanDescribeSelfWithPropertyDescription) { } // Tests that Property() can explain the result of matching a pointer. -TEST(PropertyForPointerTest, CanExplainMatchResult) { +TEST_P(PropertyForPointerTestP, CanExplainMatchResult) { Matcher m = Property(&AClass::n, Ge(0)); AClass a; @@ -881,7 +893,7 @@ TEST(PropertyForPointerTest, CanExplainMatchResult) { Explain(m, &a)); } -TEST(PropertyForPointerTest, CanExplainMatchResultWithPropertyName) { +TEST_P(PropertyForPointerTestP, CanExplainMatchResultWithPropertyName) { Matcher m = Property("fancy_name", &AClass::n, Ge(0)); AClass a; @@ -905,6 +917,8 @@ std::string IntToStringFunction(int input) { return input == 1 ? "foo" : "bar"; } +INSTANTIATE_GTEST_MATCHER_TEST_P(ResultOfTest); + TEST(ResultOfTest, WorksForFunctionPointers) { Matcher matcher = ResultOf(&IntToStringFunction, Eq(std::string("foo"))); @@ -939,7 +953,7 @@ TEST(ResultOfTest, CanDescribeItselfWithResultDescription) { // Tests that ResultOf() can explain the match result. int IntFunction(int input) { return input == 42 ? 80 : 90; } -TEST(ResultOfTest, CanExplainMatchResult) { +TEST_P(ResultOfTestP, CanExplainMatchResult) { Matcher matcher = ResultOf(&IntFunction, Ge(85)); EXPECT_EQ("which is mapped by the given callable to 90" + OfType("int"), Explain(matcher, 36)); @@ -950,7 +964,7 @@ TEST(ResultOfTest, CanExplainMatchResult) { Explain(matcher, 36)); } -TEST(ResultOfTest, CanExplainMatchResultWithResultDescription) { +TEST_P(ResultOfTestP, CanExplainMatchResultWithResultDescription) { Matcher matcher = ResultOf("magic int conversion", &IntFunction, Ge(85)); EXPECT_EQ("whose magic int conversion is 90" + OfType("int"), Explain(matcher, 36)); @@ -1408,6 +1422,8 @@ TEST(StreamlikeTest, Iteration) { } } +INSTANTIATE_GTEST_MATCHER_TEST_P(BeginEndDistanceIsTest); + TEST(BeginEndDistanceIsTest, WorksWithForwardList) { std::forward_list container; EXPECT_THAT(container, BeginEndDistanceIs(0)); @@ -1439,7 +1455,7 @@ TEST(BeginEndDistanceIsTest, WorksWithMoveOnly) { helper.Call(MakeUniquePtrs({1, 2})); } -TEST(BeginEndDistanceIsTest, ExplainsResult) { +TEST_P(BeginEndDistanceIsTestP, ExplainsResult) { Matcher> m1 = BeginEndDistanceIs(2); Matcher> m2 = BeginEndDistanceIs(Lt(2)); Matcher> m3 = BeginEndDistanceIs(AnyOf(0, 3)); @@ -2103,7 +2119,9 @@ TEST_F(UnorderedElementsAreTest, DescribeNegation) { // Tests Each(). -TEST(EachTest, ExplainsMatchResultCorrectly) { +INSTANTIATE_GTEST_MATCHER_TEST_P(EachTest); + +TEST_P(EachTestP, ExplainsMatchResultCorrectly) { set a; // empty Matcher> m = Each(2); @@ -2594,7 +2612,7 @@ TEST(ElementsAreTest, DoesNotExplainTrivialMatch) { EXPECT_EQ("", Explain(m, test_list)); // No need to explain anything. } -TEST(ElementsAreTest, ExplainsNonTrivialMatch) { +TEST_P(ElementsAreTestP, ExplainsNonTrivialMatch) { Matcher&> m = ElementsAre(GreaterThan(1), 0, GreaterThan(2)); @@ -2617,7 +2635,7 @@ TEST(ElementsAreTest, CanExplainMismatchWrongSize) { EXPECT_EQ("which has 1 element", Explain(m, test_list)); } -TEST(ElementsAreTest, CanExplainMismatchRightSize) { +TEST_P(ElementsAreTestP, CanExplainMismatchRightSize) { Matcher&> m = ElementsAre(1, GreaterThan(5)); vector v; @@ -2970,6 +2988,8 @@ TEST(ElementsAreArrayTest, SourceLifeSpan) { // Tests Contains(). +INSTANTIATE_GTEST_MATCHER_TEST_P(ContainsTest); + TEST(ContainsTest, ListMatchesWhenElementIsInContainer) { list some_list; some_list.push_back(3); @@ -3023,7 +3043,7 @@ TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) { EXPECT_THAT(c_string_set, Not(Contains(std::string("goodbye")))); } -TEST(ContainsTest, ExplainsMatchResultCorrectly) { +TEST_P(ContainsTestP, ExplainsMatchResultCorrectly) { const int a[2] = {1, 2}; Matcher m = Contains(2); EXPECT_EQ("whose element #1 matches", Explain(m, a)); diff --git a/googlemock/test/gmock-matchers-misc_test.cc b/googlemock/test/gmock-matchers-misc_test.cc index efb0059..c68431c 100644 --- a/googlemock/test/gmock-matchers-misc_test.cc +++ b/googlemock/test/gmock-matchers-misc_test.cc @@ -637,7 +637,9 @@ TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) { FormatMatcherDescription(false, "IsInRange", {"a", "b"}, {"5", "8"})); } -TEST(MatcherTupleTest, ExplainsMatchFailure) { +INSTANTIATE_GTEST_MATCHER_TEST_P(MatcherTupleTest); + +TEST_P(MatcherTupleTestP, ExplainsMatchFailure) { stringstream ss1; ExplainMatchFailureTupleTo( std::make_tuple(Matcher(Eq('a')), GreaterThan(5)), @@ -1378,6 +1380,8 @@ TEST(MatcherPnMacroTest, CanUseMatcherTypedParameterInValue) { // Tests Contains().Times(). +INSTANTIATE_GTEST_MATCHER_TEST_P(ContainsTimes); + TEST(ContainsTimes, ListMatchesWhenElementQuantityMatches) { list some_list; some_list.push_back(3); @@ -1397,7 +1401,7 @@ TEST(ContainsTimes, ListMatchesWhenElementQuantityMatches) { EXPECT_THAT(list{}, Not(Contains(_))); } -TEST(ContainsTimes, ExplainsMatchResultCorrectly) { +TEST_P(ContainsTimesP, ExplainsMatchResultCorrectly) { const int a[2] = {1, 2}; Matcher m = Contains(2).Times(3); EXPECT_EQ( @@ -1502,6 +1506,8 @@ TEST(AllOfArrayTest, Matchers) { EXPECT_THAT(1, AllOfArray({Ge(0), Ge(1)})); } +INSTANTIATE_GTEST_MATCHER_TEST_P(AnyOfArrayTest); + TEST(AnyOfArrayTest, BasicForms) { // Iterator std::vector v0{}; @@ -1554,7 +1560,7 @@ TEST(AnyOfArrayTest, Matchers) { EXPECT_THAT(1, Not(AllOfArray({Lt(0), Lt(1)}))); } -TEST(AnyOfArrayTest, ExplainsMatchResultCorrectly) { +TEST_P(AnyOfArrayTestP, ExplainsMatchResultCorrectly) { // AnyOfArray and AllOfArry use the same underlying template-template, // thus it is sufficient to test one here. const std::vector v0{}; diff --git a/googlemock/test/gmock-matchers_test.h b/googlemock/test/gmock-matchers_test.h index dbdc013..6c986e9 100644 --- a/googlemock/test/gmock-matchers_test.h +++ b/googlemock/test/gmock-matchers_test.h @@ -100,34 +100,72 @@ struct ContainerHelper { }; // For testing ExplainMatchResultTo(). -template -class GreaterThanMatcher : public MatcherInterface { - public: - explicit GreaterThanMatcher(T rhs) : rhs_(rhs) {} +template +struct GtestGreaterThanMatcher { + using is_gtest_matcher = void; - void DescribeTo(ostream* os) const override { *os << "is > " << rhs_; } + void DescribeTo(ostream* os) const { *os << "is > " << rhs; } + void DescribeNegationTo(ostream* os) const { *os << "is <= " << rhs; } - bool MatchAndExplain(T lhs, MatchResultListener* listener) const override { - if (lhs > rhs_) { - *listener << "which is " << (lhs - rhs_) << " more than " << rhs_; - } else if (lhs == rhs_) { - *listener << "which is the same as " << rhs_; + bool MatchAndExplain(T lhs, MatchResultListener* listener) const { + if (lhs > rhs) { + *listener << "which is " << (lhs - rhs) << " more than " << rhs; + } else if (lhs == rhs) { + *listener << "which is the same as " << rhs; } else { - *listener << "which is " << (rhs_ - lhs) << " less than " << rhs_; + *listener << "which is " << (rhs - lhs) << " less than " << rhs; } - return lhs > rhs_; + return lhs > rhs; } - private: - const T rhs_; + T rhs; }; template -Matcher GreaterThan(T n) { - return MakeMatcher(new GreaterThanMatcher(n)); +GtestGreaterThanMatcher::type> GtestGreaterThan( + T&& rhs) { + return {rhs}; } +// As the matcher above, but using the base class with virtual functions. +template +class GreaterThanMatcher : public MatcherInterface { + public: + explicit GreaterThanMatcher(T rhs) : impl_{rhs} {} + + void DescribeTo(ostream* os) const override { impl_.DescribeTo(os); } + void DescribeNegationTo(ostream* os) const override { + impl_.DescribeNegationTo(os); + } + + bool MatchAndExplain(T lhs, MatchResultListener* listener) const override { + return impl_.MatchAndExplain(lhs, listener); + } + + private: + const GtestGreaterThanMatcher impl_; +}; + +// Names and instantiates a new instance of GTestMatcherTestP. +#define INSTANTIATE_GTEST_MATCHER_TEST_P(TestSuite) \ + using TestSuite##P = GTestMatcherTestP; \ + INSTANTIATE_TEST_SUITE_P(MatcherInterface, TestSuite##P, Values(false)); \ + INSTANTIATE_TEST_SUITE_P(GtestMatcher, TestSuite##P, Values(true)) + +class GTestMatcherTestP : public testing::TestWithParam { + public: + template + Matcher GreaterThan(T n) { + if (use_gtest_matcher_) { + return GtestGreaterThan(n); + } else { + return MakeMatcher(new GreaterThanMatcher(n)); + } + } + const bool use_gtest_matcher_ = GetParam(); +}; + // Returns the description of the given matcher. template std::string Describe(const Matcher& m) { -- cgit v0.12