diff options
Diffstat (limited to 'testing/gmock/test/gmock-matchers_test.cc')
-rw-r--r-- | testing/gmock/test/gmock-matchers_test.cc | 297 |
1 files changed, 253 insertions, 44 deletions
diff --git a/testing/gmock/test/gmock-matchers_test.cc b/testing/gmock/test/gmock-matchers_test.cc index 3541eef..20b9387 100644 --- a/testing/gmock/test/gmock-matchers_test.cc +++ b/testing/gmock/test/gmock-matchers_test.cc @@ -42,6 +42,7 @@ #include <set> #include <sstream> #include <string> +#include <utility> #include <vector> #include <gmock/gmock.h> #include <gtest/gtest.h> @@ -59,6 +60,8 @@ bool SkipPrefix(const char* prefix, const char** pstr); namespace gmock_matchers_test { +using std::map; +using std::multimap; using std::stringstream; using std::tr1::make_tuple; using testing::A; @@ -75,6 +78,8 @@ using testing::FloatEq; using testing::Ge; using testing::Gt; using testing::HasSubstr; +using testing::IsNull; +using testing::Key; using testing::Le; using testing::Lt; using testing::MakeMatcher; @@ -88,6 +93,7 @@ using testing::NanSensitiveFloatEq; using testing::Ne; using testing::Not; using testing::NotNull; +using testing::Pair; using testing::Pointee; using testing::PolymorphicMatcher; using testing::Property; @@ -123,6 +129,35 @@ using testing::MatchesRegex; using testing::internal::RE; #endif // GMOCK_HAS_REGEX +// For testing ExplainMatchResultTo(). +class GreaterThanMatcher : public MatcherInterface<int> { + public: + explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} + + virtual bool Matches(int lhs) const { return lhs > rhs_; } + + virtual void DescribeTo(::std::ostream* os) const { + *os << "is greater than " << rhs_; + } + + virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const { + const int diff = lhs - rhs_; + if (diff > 0) { + *os << "is " << diff << " more than " << rhs_; + } else if (diff == 0) { + *os << "is the same as " << rhs_; + } else { + *os << "is " << -diff << " less than " << rhs_; + } + } + private: + const int rhs_; +}; + +Matcher<int> GreaterThan(int n) { + return MakeMatcher(new GreaterThanMatcher(n)); +} + // Returns the description of the given matcher. template <typename T> string Describe(const Matcher<T>& m) { @@ -651,6 +686,42 @@ TEST(NeTest, CanDescribeSelf) { EXPECT_EQ("is not equal to 5", Describe(m)); } +// Tests that IsNull() matches any NULL pointer of any type. +TEST(IsNullTest, MatchesNullPointer) { + Matcher<int*> m1 = IsNull(); + int* p1 = NULL; + int n = 0; + EXPECT_TRUE(m1.Matches(p1)); + EXPECT_FALSE(m1.Matches(&n)); + + Matcher<const char*> m2 = IsNull(); + const char* p2 = NULL; + EXPECT_TRUE(m2.Matches(p2)); + EXPECT_FALSE(m2.Matches("hi")); + +#if !GTEST_OS_SYMBIAN + // Nokia's Symbian compiler generates: + // gmock-matchers.h: ambiguous access to overloaded function + // gmock-matchers.h: 'testing::Matcher<void *>::Matcher(void *)' + // gmock-matchers.h: 'testing::Matcher<void *>::Matcher(const testing:: + // MatcherInterface<void *> *)' + // gmock-matchers.h: (point of instantiation: 'testing:: + // gmock_matchers_test::IsNullTest_MatchesNullPointer_Test::TestBody()') + // gmock-matchers.h: (instantiating: 'testing::PolymorphicMatc + Matcher<void*> m3 = IsNull(); + void* p3 = NULL; + EXPECT_TRUE(m3.Matches(p3)); + EXPECT_FALSE(m3.Matches(reinterpret_cast<void*>(0xbeef))); +#endif +} + +// Tests that IsNull() describes itself properly. +TEST(IsNullTest, CanDescribeSelf) { + Matcher<int*> m = IsNull(); + EXPECT_EQ("is NULL", Describe(m)); + EXPECT_EQ("is not NULL", DescribeNegation(m)); +} + // Tests that NotNull() matches any non-NULL pointer of any type. TEST(NotNullTest, MatchesNonNullPointer) { Matcher<int*> m1 = NotNull(); @@ -850,6 +921,136 @@ TEST(HasSubstrTest, CanDescribeSelf) { EXPECT_EQ("has substring \"foo\\n\\\"\"", Describe(m)); } +TEST(KeyTest, CanDescribeSelf) { + Matcher<const std::pair<std::string, int>&> m = Key("foo"); + EXPECT_EQ("has a key that is equal to \"foo\"", Describe(m)); +} + +TEST(KeyTest, MatchesCorrectly) { + std::pair<int, std::string> p(25, "foo"); + EXPECT_THAT(p, Key(25)); + EXPECT_THAT(p, Not(Key(42))); + EXPECT_THAT(p, Key(Ge(20))); + EXPECT_THAT(p, Not(Key(Lt(25)))); +} + +TEST(KeyTest, SafelyCastsInnerMatcher) { + Matcher<int> is_positive = Gt(0); + Matcher<int> is_negative = Lt(0); + std::pair<char, bool> p('a', true); + EXPECT_THAT(p, Key(is_positive)); + EXPECT_THAT(p, Not(Key(is_negative))); +} + +TEST(KeyTest, InsideContainsUsingMap) { + std::map<int, char> container; + container.insert(std::make_pair(1, 'a')); + container.insert(std::make_pair(2, 'b')); + container.insert(std::make_pair(4, 'c')); + EXPECT_THAT(container, Contains(Key(1))); + EXPECT_THAT(container, Not(Contains(Key(3)))); +} + +TEST(KeyTest, InsideContainsUsingMultimap) { + std::multimap<int, char> container; + container.insert(std::make_pair(1, 'a')); + container.insert(std::make_pair(2, 'b')); + container.insert(std::make_pair(4, 'c')); + + EXPECT_THAT(container, Not(Contains(Key(25)))); + container.insert(std::make_pair(25, 'd')); + EXPECT_THAT(container, Contains(Key(25))); + container.insert(std::make_pair(25, 'e')); + EXPECT_THAT(container, Contains(Key(25))); + + EXPECT_THAT(container, Contains(Key(1))); + EXPECT_THAT(container, Not(Contains(Key(3)))); +} + +TEST(PairTest, Typing) { + // Test verifies the following type conversions can be compiled. + Matcher<const std::pair<const char*, int>&> m1 = Pair("foo", 42); + Matcher<const std::pair<const char*, int> > m2 = Pair("foo", 42); + Matcher<std::pair<const char*, int> > m3 = Pair("foo", 42); + + Matcher<std::pair<int, const std::string> > m4 = Pair(25, "42"); + Matcher<std::pair<const std::string, int> > m5 = Pair("25", 42); +} + +TEST(PairTest, CanDescribeSelf) { + Matcher<const std::pair<std::string, int>&> m1 = Pair("foo", 42); + EXPECT_EQ("has a first field that is equal to \"foo\"" + ", and has a second field that is equal to 42", + Describe(m1)); + EXPECT_EQ("has a first field that is not equal to \"foo\"" + ", or has a second field that is not equal to 42", + DescribeNegation(m1)); + // Double and triple negation (1 or 2 times not and description of negation). + Matcher<const std::pair<int, int>&> m2 = Not(Pair(Not(13), 42)); + EXPECT_EQ("has a first field that is not equal to 13" + ", and has a second field that is equal to 42", + DescribeNegation(m2)); +} + +TEST(PairTest, CanExplainMatchResultTo) { + const Matcher<std::pair<int, int> > m0 = Pair(0, 0); + EXPECT_EQ("", Explain(m0, std::make_pair(25, 42))); + + const Matcher<std::pair<int, int> > m1 = Pair(GreaterThan(0), 0); + EXPECT_EQ("the first field is 25 more than 0", + Explain(m1, std::make_pair(25, 42))); + + const Matcher<std::pair<int, int> > m2 = Pair(0, GreaterThan(0)); + EXPECT_EQ("the second field is 42 more than 0", + Explain(m2, std::make_pair(25, 42))); + + const Matcher<std::pair<int, int> > m3 = Pair(GreaterThan(0), GreaterThan(0)); + EXPECT_EQ("the first field is 25 more than 0" + ", and the second field is 42 more than 0", + Explain(m3, std::make_pair(25, 42))); +} + +TEST(PairTest, MatchesCorrectly) { + std::pair<int, std::string> p(25, "foo"); + + // Both fields match. + EXPECT_THAT(p, Pair(25, "foo")); + EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o"))); + + // 'first' doesnt' match, but 'second' matches. + EXPECT_THAT(p, Not(Pair(42, "foo"))); + EXPECT_THAT(p, Not(Pair(Lt(25), "foo"))); + + // 'first' matches, but 'second' doesn't match. + EXPECT_THAT(p, Not(Pair(25, "bar"))); + EXPECT_THAT(p, Not(Pair(25, Not("foo")))); + + // Neither field matches. + EXPECT_THAT(p, Not(Pair(13, "bar"))); + EXPECT_THAT(p, Not(Pair(Lt(13), HasSubstr("a")))); +} + +TEST(PairTest, SafelyCastsInnerMatchers) { + Matcher<int> is_positive = Gt(0); + Matcher<int> is_negative = Lt(0); + std::pair<char, bool> p('a', true); + EXPECT_THAT(p, Pair(is_positive, _)); + EXPECT_THAT(p, Not(Pair(is_negative, _))); + EXPECT_THAT(p, Pair(_, is_positive)); + EXPECT_THAT(p, Not(Pair(_, is_negative))); +} + +TEST(PairTest, InsideContainsUsingMap) { + std::map<int, char> container; + container.insert(std::make_pair(1, 'a')); + container.insert(std::make_pair(2, 'b')); + container.insert(std::make_pair(4, 'c')); + EXPECT_THAT(container, Contains(Pair(1, 'a'))); + EXPECT_THAT(container, Contains(Pair(1, _))); + EXPECT_THAT(container, Contains(Pair(_, 'a'))); + EXPECT_THAT(container, Not(Contains(Pair(3, _)))); +} + // Tests StartsWith(s). TEST(StartsWithTest, MatchesStringWithGivenPrefix) { @@ -1735,17 +1936,23 @@ TEST(MatcherAssertionTest, WorksWhenMatcherIsNotSatisfied) { // which cannot reference auto variables. static int n; n = 5; - EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Gt(10)) << "This should fail.", + + // VC++ prior to version 8.0 SP1 has a bug where it will not see any + // functions declared in the namespace scope from within nested classes. + // EXPECT/ASSERT_(NON)FATAL_FAILURE macros use nested classes so that all + // namespace-level functions invoked inside them need to be explicitly + // resolved. + EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Gt(10)), "Value of: n\n" "Expected: is greater than 10\n" - " Actual: 5\n" - "This should fail."); + " Actual: 5"); n = 0; - EXPECT_NONFATAL_FAILURE(EXPECT_THAT(n, AllOf(Le(7), Ge(5))), - "Value of: n\n" - "Expected: (is less than or equal to 7) and " - "(is greater than or equal to 5)\n" - " Actual: 0"); + EXPECT_NONFATAL_FAILURE( + EXPECT_THAT(n, ::testing::AllOf(::testing::Le(7), ::testing::Ge(5))), + "Value of: n\n" + "Expected: (is less than or equal to 7) and " + "(is greater than or equal to 5)\n" + " Actual: 0"); } // Tests that ASSERT_THAT() and EXPECT_THAT() work when the argument @@ -1756,16 +1963,28 @@ TEST(MatcherAssertionTest, WorksForByRefArguments) { static int n; n = 0; EXPECT_THAT(n, AllOf(Le(7), Ref(n))); - EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Not(Ref(n))), + EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Not(::testing::Ref(n))), "Value of: n\n" "Expected: does not reference the variable @"); // Tests the "Actual" part. - EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Not(Ref(n))), + EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Not(::testing::Ref(n))), "Actual: 0 (is located @"); } +#if !GTEST_OS_SYMBIAN // Tests that ASSERT_THAT() and EXPECT_THAT() work when the matcher is // monomorphic. + +// ASSERT_THAT("hello", starts_with_he) fails to compile with Nokia's +// Symbian compiler: it tries to compile +// template<T, U> class MatcherCastImpl { ... +// virtual bool Matches(T x) const { +// return source_matcher_.Matches(static_cast<U>(x)); +// with U == string and T == const char* +// With ASSERT_THAT("hello"...) changed to ASSERT_THAT(string("hello") ... ) +// the compiler silently crashes with no output. +// If MatcherCastImpl is changed to use U(x) instead of static_cast<U>(x) +// the code compiles but the converted string is bogus. TEST(MatcherAssertionTest, WorksForMonomorphicMatcher) { Matcher<const char*> starts_with_he = StartsWith("he"); ASSERT_THAT("hello", starts_with_he); @@ -1779,6 +1998,7 @@ TEST(MatcherAssertionTest, WorksForMonomorphicMatcher) { "Expected: is greater than 5\n" " Actual: 5"); } +#endif // !GTEST_OS_SYMBIAN // Tests floating-point matchers. template <typename RawType> @@ -2095,35 +2315,6 @@ TEST(PointeeTest, CanDescribeSelf) { DescribeNegation(m)); } -// For testing ExplainMatchResultTo(). -class GreaterThanMatcher : public MatcherInterface<int> { - public: - explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} - - virtual bool Matches(int lhs) const { return lhs > rhs_; } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "is greater than " << rhs_; - } - - virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const { - const int diff = lhs - rhs_; - if (diff > 0) { - *os << "is " << diff << " more than " << rhs_; - } else if (diff == 0) { - *os << "is the same as " << rhs_; - } else { - *os << "is " << -diff << " less than " << rhs_; - } - } - private: - const int rhs_; -}; - -Matcher<int> GreaterThan(int n) { - return MakeMatcher(new GreaterThanMatcher(n)); -} - TEST(PointeeTest, CanExplainMatchResult) { const Matcher<const string*> m = Pointee(StartsWith("Hi")); @@ -2623,15 +2814,13 @@ TEST(ResultOfTest, WorksForCompatibleMatcherTypes) { EXPECT_FALSE(matcher.Matches(42)); } -#if GTEST_HAS_DEATH_TEST // Tests that the program aborts when ResultOf is passed // a NULL function pointer. TEST(ResultOfDeathTest, DiesOnNullFunctionPointers) { - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( ResultOf(static_cast<string(*)(int)>(NULL), Eq(string("foo"))), "NULL function pointer is passed into ResultOf\\(\\)\\."); } -#endif // GTEST_HAS_DEATH_TEST // Tests that ResultOf(f, ...) compiles and works as expected when f is a // function reference. @@ -2696,7 +2885,6 @@ TEST(ResultOfTest, WorksForReferencingCallables) { EXPECT_FALSE(matcher3.Matches(n2)); } - class DivisibleByImpl { public: explicit DivisibleByImpl(int divider) : divider_(divider) {} @@ -2714,9 +2902,11 @@ class DivisibleByImpl { *os << "is not divisible by " << divider_; } + void set_divider(int divider) { divider_ = divider; } int divider() const { return divider_; } + private: - const int divider_; + int divider_; }; // For testing using ExplainMatchResultTo() with polymorphic matchers. @@ -2810,6 +3000,7 @@ TEST(ByRefTest, AllowsNotCopyableValueInMatchers) { EXPECT_TRUE(m.Matches(n2)); } +#if GTEST_HAS_TYPED_TEST // Tests ContainerEq with different container types, and // different element types. @@ -2878,6 +3069,7 @@ TYPED_TEST(ContainerEqTest, DuplicateDifference) { // But in any case there should be no explanation. EXPECT_EQ("", Explain(m, test_set)); } +#endif // GTEST_HAS_TYPED_TEST // Tests that mutliple missing values are reported. // Using just vector here, so order is predicatble. @@ -3296,5 +3488,22 @@ TEST(FormatMatcherDescriptionTest, Strings(params, params + 1))); } +// Tests PolymorphicMatcher::mutable_impl(). +TEST(PolymorphicMatcherTest, CanAccessMutableImpl) { + PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42)); + DivisibleByImpl& impl = m.mutable_impl(); + EXPECT_EQ(42, impl.divider()); + + impl.set_divider(0); + EXPECT_EQ(0, m.mutable_impl().divider()); +} + +// Tests PolymorphicMatcher::impl(). +TEST(PolymorphicMatcherTest, CanAccessImpl) { + const PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42)); + const DivisibleByImpl& impl = m.impl(); + EXPECT_EQ(42, impl.divider()); +} + } // namespace gmock_matchers_test } // namespace testing |