diff options
Diffstat (limited to 'googlemock/test')
-rw-r--r-- | googlemock/test/gmock-actions_test.cc | 162 | ||||
-rw-r--r-- | googlemock/test/gmock-generated-actions_test.cc | 14 | ||||
-rw-r--r-- | googlemock/test/gmock-generated-function-mockers_test.cc | 23 | ||||
-rw-r--r-- | googlemock/test/gmock-generated-internal-utils_test.cc | 20 | ||||
-rw-r--r-- | googlemock/test/gmock-generated-matchers_test.cc | 63 | ||||
-rw-r--r-- | googlemock/test/gmock-matchers_test.cc | 1196 | ||||
-rw-r--r-- | googlemock/test/gmock-more-actions_test.cc | 17 | ||||
-rw-r--r-- | googlemock/test/gmock-nice-strict_test.cc | 71 | ||||
-rw-r--r-- | googlemock/test/gmock-spec-builders_test.cc | 76 | ||||
-rw-r--r-- | googlemock/test/gmock_output_test_.cc | 15 | ||||
-rw-r--r-- | googlemock/test/gmock_output_test_golden.txt | 9 |
11 files changed, 1555 insertions, 111 deletions
diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index 01286634..7fbb50d3 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -33,6 +33,15 @@ // // This file tests the built-in actions. +// Silence C4800 (C4800: 'int *const ': forcing value +// to bool 'true' or 'false') for MSVC 14,15 +#ifdef _MSC_VER +#if _MSC_VER <= 1900 +# pragma warning(push) +# pragma warning(disable:4800) +#endif +#endif + #include "gmock/gmock-actions.h" #include <algorithm> #include <iterator> @@ -65,6 +74,7 @@ using testing::ReturnRef; using testing::ReturnRefOfCopy; using testing::SetArgPointee; using testing::SetArgumentPointee; +using testing::Unused; using testing::_; using testing::get; using testing::internal::BuiltInDefaultValue; @@ -704,6 +714,9 @@ class MockClass { MOCK_METHOD0(MakeUnique, std::unique_ptr<int>()); MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>()); MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>()); + MOCK_METHOD1(TakeUnique, int(std::unique_ptr<int>)); + MOCK_METHOD2(TakeUnique, + int(const std::unique_ptr<int>&, std::unique_ptr<int>)); #endif private: @@ -755,7 +768,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) { } // Tests that DoDefault() returns the default value set by -// DefaultValue<T>::Set() when it's not overridden by an ON_CALL(). +// DefaultValue<T>::Set() when it's not overriden by an ON_CALL(). TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { DefaultValue<int>::Set(1); MockClass mock; @@ -1410,6 +1423,153 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) { EXPECT_EQ(7, *vresult[0]); } +TEST(MockMethodTest, CanTakeMoveOnlyValue) { + MockClass mock; + auto make = [](int i) { return std::unique_ptr<int>(new int(i)); }; + + EXPECT_CALL(mock, TakeUnique(_)).WillRepeatedly([](std::unique_ptr<int> i) { + return *i; + }); + // DoAll() does not compile, since it would move from its arguments twice. + // EXPECT_CALL(mock, TakeUnique(_, _)) + // .WillRepeatedly(DoAll(Invoke([](std::unique_ptr<int> j) {}), + // Return(1))); + EXPECT_CALL(mock, TakeUnique(testing::Pointee(7))) + .WillOnce(Return(-7)) + .RetiresOnSaturation(); + EXPECT_CALL(mock, TakeUnique(testing::IsNull())) + .WillOnce(Return(-1)) + .RetiresOnSaturation(); + + EXPECT_EQ(5, mock.TakeUnique(make(5))); + EXPECT_EQ(-7, mock.TakeUnique(make(7))); + EXPECT_EQ(7, mock.TakeUnique(make(7))); + EXPECT_EQ(7, mock.TakeUnique(make(7))); + EXPECT_EQ(-1, mock.TakeUnique({})); + + // Some arguments are moved, some passed by reference. + auto lvalue = make(6); + EXPECT_CALL(mock, TakeUnique(_, _)) + .WillOnce([](const std::unique_ptr<int>& i, std::unique_ptr<int> j) { + return *i * *j; + }); + EXPECT_EQ(42, mock.TakeUnique(lvalue, make(7))); + + // The unique_ptr can be saved by the action. + std::unique_ptr<int> saved; + EXPECT_CALL(mock, TakeUnique(_)).WillOnce([&saved](std::unique_ptr<int> i) { + saved = std::move(i); + return 0; + }); + EXPECT_EQ(0, mock.TakeUnique(make(42))); + EXPECT_EQ(42, *saved); +} + #endif // GTEST_HAS_STD_UNIQUE_PTR_ +#if GTEST_LANG_CXX11 +// Tests for std::function based action. + +int Add(int val, int& ref, int* ptr) { // NOLINT + int result = val + ref + *ptr; + ref = 42; + *ptr = 43; + return result; +} + +int Deref(std::unique_ptr<int> ptr) { return *ptr; } + +struct Double { + template <typename T> + T operator()(T t) { return 2 * t; } +}; + +std::unique_ptr<int> UniqueInt(int i) { + return std::unique_ptr<int>(new int(i)); +} + +TEST(FunctorActionTest, ActionFromFunction) { + Action<int(int, int&, int*)> a = &Add; + int x = 1, y = 2, z = 3; + EXPECT_EQ(6, a.Perform(std::forward_as_tuple(x, y, &z))); + EXPECT_EQ(42, y); + EXPECT_EQ(43, z); + + Action<int(std::unique_ptr<int>)> a1 = &Deref; + EXPECT_EQ(7, a1.Perform(std::make_tuple(UniqueInt(7)))); +} + +TEST(FunctorActionTest, ActionFromLambda) { + Action<int(bool, int)> a1 = [](bool b, int i) { return b ? i : 0; }; + EXPECT_EQ(5, a1.Perform(make_tuple(true, 5))); + EXPECT_EQ(0, a1.Perform(make_tuple(false, 5))); + + std::unique_ptr<int> saved; + Action<void(std::unique_ptr<int>)> a2 = [&saved](std::unique_ptr<int> p) { + saved = std::move(p); + }; + a2.Perform(make_tuple(UniqueInt(5))); + EXPECT_EQ(5, *saved); +} + +TEST(FunctorActionTest, PolymorphicFunctor) { + Action<int(int)> ai = Double(); + EXPECT_EQ(2, ai.Perform(make_tuple(1))); + Action<double(double)> ad = Double(); // Double? Double double! + EXPECT_EQ(3.0, ad.Perform(make_tuple(1.5))); +} + +TEST(FunctorActionTest, TypeConversion) { + // Numeric promotions are allowed. + const Action<bool(int)> a1 = [](int i) { return i > 1; }; + const Action<int(bool)> a2 = Action<int(bool)>(a1); + EXPECT_EQ(1, a1.Perform(make_tuple(42))); + EXPECT_EQ(0, a2.Perform(make_tuple(42))); + + // Implicit constructors are allowed. + const Action<bool(std::string)> s1 = [](std::string s) { return !s.empty(); }; + const Action<int(const char*)> s2 = Action<int(const char*)>(s1); + EXPECT_EQ(0, s2.Perform(make_tuple(""))); + EXPECT_EQ(1, s2.Perform(make_tuple("hello"))); + + // Also between the lambda and the action itself. + const Action<bool(std::string)> x = [](Unused) { return 42; }; + EXPECT_TRUE(x.Perform(make_tuple("hello"))); +} + +TEST(FunctorActionTest, UnusedArguments) { + // Verify that users can ignore uninteresting arguments. + Action<int(int, double y, double z)> a = + [](int i, Unused, Unused) { return 2 * i; }; + tuple<int, double, double> dummy = make_tuple(3, 7.3, 9.44); + EXPECT_EQ(6, a.Perform(dummy)); +} + +// Test that basic built-in actions work with move-only arguments. +// TODO(rburny): Currently, almost all ActionInterface-based actions will not +// work, even if they only try to use other, copyable arguments. Implement them +// if necessary (but note that DoAll cannot work on non-copyable types anyway - +// so maybe it's better to make users use lambdas instead. +TEST(MoveOnlyArgumentsTest, ReturningActions) { + Action<int(std::unique_ptr<int>)> a = Return(1); + EXPECT_EQ(1, a.Perform(make_tuple(nullptr))); + + a = testing::WithoutArgs([]() { return 7; }); + EXPECT_EQ(7, a.Perform(make_tuple(nullptr))); + + Action<void(std::unique_ptr<int>, int*)> a2 = testing::SetArgPointee<1>(3); + int x = 0; + a2.Perform(make_tuple(nullptr, &x)); + EXPECT_EQ(x, 3); +} + +#endif // GTEST_LANG_CXX11 + } // Unnamed namespace + +#ifdef _MSC_VER +#if _MSC_VER == 1900 +# pragma warning(pop) +#endif +#endif + diff --git a/googlemock/test/gmock-generated-actions_test.cc b/googlemock/test/gmock-generated-actions_test.cc index 80bcb31c..40bbe6d9 100644 --- a/googlemock/test/gmock-generated-actions_test.cc +++ b/googlemock/test/gmock-generated-actions_test.cc @@ -374,10 +374,10 @@ class SubstractAction : public ActionInterface<int(int, int)> { // NOLINT }; TEST(WithArgsTest, NonInvokeAction) { - Action<int(const string&, int, int)> a = // NOLINT + Action<int(const std::string&, int, int)> a = // NOLINT WithArgs<2, 1>(MakeAction(new SubstractAction)); - string s("hello"); - EXPECT_EQ(8, a.Perform(tuple<const string&, int, int>(s, 2, 10))); + tuple<std::string, int, int> dummy = make_tuple(std::string("hi"), 2, 10); + EXPECT_EQ(8, a.Perform(dummy)); } // Tests using WithArgs to pass all original arguments in the original order. @@ -754,7 +754,8 @@ TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) { TEST(ActionPMacroTest, WorksInCompatibleMockFunction) { Action<std::string(const std::string& s)> a1 = Plus("tail"); const std::string re = "re"; - EXPECT_EQ("retail", a1.Perform(tuple<const std::string&>(re))); + tuple<const std::string> dummy = make_tuple(re); + EXPECT_EQ("retail", a1.Perform(dummy)); } // Tests that we can use ACTION*() to define actions overloaded on the @@ -796,7 +797,8 @@ TEST(ActionPnMacroTest, WorksFor3Parameters) { Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">"); const std::string re = "re"; - EXPECT_EQ("retail->", a2.Perform(tuple<const std::string&>(re))); + tuple<const std::string> dummy = make_tuple(re); + EXPECT_EQ("retail->", a2.Perform(dummy)); } ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; } @@ -1120,7 +1122,7 @@ TEST(ActionTemplateTest, WorksForIntegralTemplateParams) { EXPECT_FALSE(b); // Verifies that resetter is deleted. } -// Tests that ACTION_TEMPLATE works for a template with template parameters. +// Tests that ACTION_TEMPLATES works for template template parameters. ACTION_TEMPLATE(ReturnSmartPointer, HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class, Pointer), diff --git a/googlemock/test/gmock-generated-function-mockers_test.cc b/googlemock/test/gmock-generated-function-mockers_test.cc index 08e5eba1..0ff37556 100644 --- a/googlemock/test/gmock-generated-function-mockers_test.cc +++ b/googlemock/test/gmock-generated-function-mockers_test.cc @@ -620,5 +620,28 @@ TEST(MockFunctionTest, AsStdFunctionReturnsReference) { } #endif // GTEST_HAS_STD_FUNCTION_ +struct MockMethodSizes0 { + MOCK_METHOD0(func, void()); +}; +struct MockMethodSizes1 { + MOCK_METHOD1(func, void(int)); +}; +struct MockMethodSizes2 { + MOCK_METHOD2(func, void(int, int)); +}; +struct MockMethodSizes3 { + MOCK_METHOD3(func, void(int, int, int)); +}; +struct MockMethodSizes4 { + MOCK_METHOD4(func, void(int, int, int, int)); +}; + +TEST(MockFunctionTest, MockMethodSizeOverhead) { + EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1)); + EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2)); + EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3)); + EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4)); +} + } // namespace gmock_generated_function_mockers_test } // namespace testing diff --git a/googlemock/test/gmock-generated-internal-utils_test.cc b/googlemock/test/gmock-generated-internal-utils_test.cc index e0a535a3..2e5abe56 100644 --- a/googlemock/test/gmock-generated-internal-utils_test.cc +++ b/googlemock/test/gmock-generated-internal-utils_test.cc @@ -63,10 +63,10 @@ TEST(MatcherTupleTest, ForSize2) { } TEST(MatcherTupleTest, ForSize5) { - CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char>, Matcher<bool>, - Matcher<double>, Matcher<char*> >, - MatcherTuple<tuple<int, char, bool, double, char*> - >::type>(); + CompileAssertTypesEqual< + tuple<Matcher<int>, Matcher<char>, Matcher<bool>, Matcher<double>, + Matcher<char*> >, + MatcherTuple<tuple<int, char, bool, double, char*> >::type>(); } // Tests the Function template struct. @@ -97,8 +97,9 @@ TEST(FunctionTest, Binary) { CompileAssertTypesEqual<bool, F::Argument1>(); CompileAssertTypesEqual<const long&, F::Argument2>(); // NOLINT CompileAssertTypesEqual<tuple<bool, const long&>, F::ArgumentTuple>(); // NOLINT - CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<const long&> >, // NOLINT - F::ArgumentMatcherTuple>(); + CompileAssertTypesEqual< + tuple<Matcher<bool>, Matcher<const long&> >, // NOLINT + F::ArgumentMatcherTuple>(); CompileAssertTypesEqual<void(bool, const long&), F::MakeResultVoid>(); // NOLINT CompileAssertTypesEqual<IgnoredValue(bool, const long&), // NOLINT F::MakeResultIgnoredValue>(); @@ -114,9 +115,10 @@ TEST(FunctionTest, LongArgumentList) { CompileAssertTypesEqual<const long&, F::Argument5>(); // NOLINT CompileAssertTypesEqual<tuple<bool, int, char*, int&, const long&>, // NOLINT F::ArgumentTuple>(); - CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, - Matcher<int&>, Matcher<const long&> >, // NOLINT - F::ArgumentMatcherTuple>(); + CompileAssertTypesEqual< + tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, Matcher<int&>, + Matcher<const long&> >, // NOLINT + F::ArgumentMatcherTuple>(); CompileAssertTypesEqual<void(bool, int, char*, int&, const long&), // NOLINT F::MakeResultVoid>(); CompileAssertTypesEqual< diff --git a/googlemock/test/gmock-generated-matchers_test.cc b/googlemock/test/gmock-generated-matchers_test.cc index 6cba726d..0ebd4701 100644 --- a/googlemock/test/gmock-generated-matchers_test.cc +++ b/googlemock/test/gmock-generated-matchers_test.cc @@ -31,10 +31,19 @@ // // This file tests the built-in matchers generated by a script. +// 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-generated-matchers.h" #include <list> #include <map> +#include <memory> #include <set> #include <sstream> #include <string> @@ -57,6 +66,8 @@ using testing::get; using testing::make_tuple; using testing::tuple; using testing::_; +using testing::AllOf; +using testing::AnyOf; using testing::Args; using testing::Contains; using testing::ElementsAre; @@ -120,7 +131,7 @@ TEST(ArgsTest, AcceptsOneTemplateArg) { } TEST(ArgsTest, AcceptsTwoTemplateArgs) { - const tuple<short, int, long> t(static_cast<short>(4), 5, 6L); // NOLINT + const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<0, 1>(Lt()))); EXPECT_THAT(t, (Args<1, 2>(Lt()))); @@ -128,13 +139,13 @@ TEST(ArgsTest, AcceptsTwoTemplateArgs) { } TEST(ArgsTest, AcceptsRepeatedTemplateArgs) { - const tuple<short, int, long> t(static_cast<short>(4), 5, 6L); // NOLINT + const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<0, 0>(Eq()))); EXPECT_THAT(t, Not(Args<1, 1>(Ne()))); } TEST(ArgsTest, AcceptsDecreasingTemplateArgs) { - const tuple<short, int, long> t(static_cast<short>(4), 5, 6L); // NOLINT + const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<2, 0>(Gt()))); EXPECT_THAT(t, Not(Args<2, 1>(Lt()))); } @@ -159,7 +170,7 @@ TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) { } TEST(ArgsTest, CanBeNested) { - const tuple<short, int, long, int> t(static_cast<short>(4), 5, 6L, 6); // NOLINT + const tuple<short, int, long, int> 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())))); } @@ -1283,4 +1294,48 @@ TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) { # pragma warning(pop) #endif +#if GTEST_LANG_CXX11 + +TEST(AllOfTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(5)))); + EXPECT_THAT(p, Not(AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(3))))); +} + +TEST(AnyOfTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Lt(5)))); + EXPECT_THAT(p, Not(AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Gt(5))))); +} + +MATCHER(IsNotNull, "") { + return arg != nullptr; +} + +// Verifies that a matcher defined using MATCHER() can work on +// move-only types. +TEST(MatcherMacroTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, IsNotNull()); + EXPECT_THAT(std::unique_ptr<int>(), Not(IsNotNull())); +} + +MATCHER_P(UniquePointee, pointee, "") { + return *arg == pointee; +} + +// Verifies that a matcher defined using MATCHER_P*() can work on +// move-only types. +TEST(MatcherPMacroTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, UniquePointee(3)); + EXPECT_THAT(p, Not(UniquePointee(2))); +} + +#endif // GTEST_LASNG_CXX11 + } // namespace + +#ifdef _MSC_VER +# pragma warning(pop) +#endif diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 829935ef..b4224651 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -45,6 +45,7 @@ #include <limits> #include <list> #include <map> +#include <memory> #include <set> #include <sstream> #include <string> @@ -58,13 +59,11 @@ # include <forward_list> // NOLINT #endif -// Disable MSVC2015 warning for std::pair: "decorated name length exceeded, name was truncated". -#if defined(_MSC_VER) && (_MSC_VER == 1900) -# pragma warning(disable:4503) +#if GTEST_LANG_CXX11 +# include <type_traits> #endif namespace testing { - namespace gmock_matchers_test { using std::greater; @@ -200,17 +199,13 @@ std::string OfType(const std::string& type_name) { // Returns the description of the given matcher. template <typename T> std::string Describe(const Matcher<T>& m) { - stringstream ss; - m.DescribeTo(&ss); - return ss.str(); + return DescribeMatcher<T>(m); } // Returns the description of the negation of the given matcher. template <typename T> std::string DescribeNegation(const Matcher<T>& m) { - stringstream ss; - m.DescribeNegationTo(&ss); - return ss.str(); + return DescribeMatcher<T>(m, true); } // Returns the reason why x matches, or doesn't match, m. @@ -221,6 +216,12 @@ std::string Explain(const MatcherType& m, const Value& x) { return listener.str(); } +TEST(MonotonicMatcherTest, IsPrintable) { + stringstream ss; + ss << GreaterThan(5); + EXPECT_EQ("is > 5", ss.str()); +} + TEST(MatchResultListenerTest, StreamingWorks) { StringMatchResultListener listener; listener << "hi" << 5; @@ -332,6 +333,22 @@ TEST(MatcherTest, CanBeImplicitlyConstructedFromNULL) { EXPECT_FALSE(m1.Matches(&n)); } +// Tests that matchers can be constructed from a variable that is not properly +// defined. This should be illegal, but many users rely on this accidentally. +struct Undefined { + virtual ~Undefined() = 0; + static const int kInt = 1; +}; + +TEST(MatcherTest, CanBeConstructedFromUndefinedVariable) { + Matcher<int> m1 = Undefined::kInt; + EXPECT_TRUE(m1.Matches(1)); + EXPECT_FALSE(m1.Matches(2)); +} + +// Test that a matcher parameterized with an abstract class compiles. +TEST(MatcherTest, CanAcceptAbstractClass) { Matcher<const Undefined&> m = _; } + // Tests that matchers are copyable. TEST(MatcherTest, IsCopyable) { // Tests the copy constructor. @@ -365,66 +382,132 @@ TEST(MatcherTest, MatchAndExplain) { } // Tests that a C-string literal can be implicitly converted to a -// Matcher<string> or Matcher<const string&>. +// Matcher<std::string> or Matcher<const std::string&>. TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { - Matcher<string> m1 = "hi"; + Matcher<std::string> m1 = "hi"; EXPECT_TRUE(m1.Matches("hi")); EXPECT_FALSE(m1.Matches("hello")); - Matcher<const string&> m2 = "hi"; + Matcher<const std::string&> m2 = "hi"; EXPECT_TRUE(m2.Matches("hi")); EXPECT_FALSE(m2.Matches("hello")); } // Tests that a string object can be implicitly converted to a -// Matcher<string> or Matcher<const string&>. +// Matcher<std::string> or Matcher<const std::string&>. TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) { - Matcher<string> m1 = string("hi"); + Matcher<std::string> m1 = std::string("hi"); + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const std::string&> m2 = std::string("hi"); + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} + +#if GTEST_HAS_GLOBAL_STRING +// Tests that a ::string object can be implicitly converted to a +// Matcher<std::string> or Matcher<const std::string&>. +TEST(StringMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { + Matcher<std::string> m1 = ::string("hi"); EXPECT_TRUE(m1.Matches("hi")); EXPECT_FALSE(m1.Matches("hello")); - Matcher<const string&> m2 = string("hi"); + Matcher<const std::string&> m2 = ::string("hi"); EXPECT_TRUE(m2.Matches("hi")); EXPECT_FALSE(m2.Matches("hello")); } +#endif // GTEST_HAS_GLOBAL_STRING -#if GTEST_HAS_STRING_PIECE_ +#if GTEST_HAS_GLOBAL_STRING // Tests that a C-string literal can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { - Matcher<StringPiece> m1 = "cats"; +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { + Matcher< ::string> m1 = "hi"; + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const ::string&> m2 = "hi"; + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} + +// Tests that a std::string object can be implicitly converted to a +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromString) { + Matcher< ::string> m1 = std::string("hi"); + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const ::string&> m2 = std::string("hi"); + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} + +// Tests that a ::string object can be implicitly converted to a +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { + Matcher< ::string> m1 = ::string("hi"); + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const ::string&> m2 = ::string("hi"); + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_ABSL +// Tests that a C-string literal can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { + Matcher<absl::string_view> m1 = "cats"; EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const StringPiece&> m2 = "cats"; + Matcher<const absl::string_view&> m2 = "cats"; EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } -// Tests that a string object can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromString) { - Matcher<StringPiece> m1 = string("cats"); +// Tests that a std::string object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromString) { + Matcher<absl::string_view> m1 = std::string("cats"); EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const StringPiece&> m2 = string("cats"); + Matcher<const absl::string_view&> m2 = std::string("cats"); EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } -// Tests that a StringPiece object can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromStringPiece) { - Matcher<StringPiece> m1 = StringPiece("cats"); +#if GTEST_HAS_GLOBAL_STRING +// Tests that a ::string object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { + Matcher<absl::string_view> m1 = ::string("cats"); EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const StringPiece&> m2 = StringPiece("cats"); + Matcher<const absl::string_view&> m2 = ::string("cats"); EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } -#endif // GTEST_HAS_STRING_PIECE_ +#endif // GTEST_HAS_GLOBAL_STRING + +// Tests that a absl::string_view object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromStringView) { + Matcher<absl::string_view> m1 = absl::string_view("cats"); + EXPECT_TRUE(m1.Matches("cats")); + EXPECT_FALSE(m1.Matches("dogs")); + + Matcher<const absl::string_view&> m2 = absl::string_view("cats"); + EXPECT_TRUE(m2.Matches("cats")); + EXPECT_FALSE(m2.Matches("dogs")); +} +#endif // GTEST_HAS_ABSL // Tests that MakeMatcher() constructs a Matcher<T> from a // MatcherInterface* without requiring the user to explicitly @@ -609,11 +692,76 @@ TEST(MatcherCastTest, FromSameType) { EXPECT_FALSE(m2.Matches(1)); } +// Tests that MatcherCast<T>(m) works when m is a value of the same type as the +// value type of the Matcher. +TEST(MatcherCastTest, FromAValue) { + Matcher<int> m = MatcherCast<int>(42); + EXPECT_TRUE(m.Matches(42)); + EXPECT_FALSE(m.Matches(239)); +} + +// Tests that MatcherCast<T>(m) works when m is a value of the type implicitly +// convertible to the value type of the Matcher. +TEST(MatcherCastTest, FromAnImplicitlyConvertibleValue) { + const int kExpected = 'c'; + Matcher<int> m = MatcherCast<int>('c'); + EXPECT_TRUE(m.Matches(kExpected)); + EXPECT_FALSE(m.Matches(kExpected + 1)); +} + +struct NonImplicitlyConstructibleTypeWithOperatorEq { + friend bool operator==( + const NonImplicitlyConstructibleTypeWithOperatorEq& /* ignored */, + int rhs) { + return 42 == rhs; + } + friend bool operator==( + int lhs, + const NonImplicitlyConstructibleTypeWithOperatorEq& /* ignored */) { + return lhs == 42; + } +}; + +// Tests that MatcherCast<T>(m) works when m is a neither a matcher nor +// implicitly convertible to the value type of the Matcher, but the value type +// of the matcher has operator==() overload accepting m. +TEST(MatcherCastTest, NonImplicitlyConstructibleTypeWithOperatorEq) { + Matcher<NonImplicitlyConstructibleTypeWithOperatorEq> m1 = + MatcherCast<NonImplicitlyConstructibleTypeWithOperatorEq>(42); + EXPECT_TRUE(m1.Matches(NonImplicitlyConstructibleTypeWithOperatorEq())); + + Matcher<NonImplicitlyConstructibleTypeWithOperatorEq> m2 = + MatcherCast<NonImplicitlyConstructibleTypeWithOperatorEq>(239); + EXPECT_FALSE(m2.Matches(NonImplicitlyConstructibleTypeWithOperatorEq())); + + // When updating the following lines please also change the comment to + // namespace convertible_from_any. + Matcher<int> m3 = + MatcherCast<int>(NonImplicitlyConstructibleTypeWithOperatorEq()); + EXPECT_TRUE(m3.Matches(42)); + EXPECT_FALSE(m3.Matches(239)); +} + +// ConvertibleFromAny does not work with MSVC. resulting in +// error C2440: 'initializing': cannot convert from 'Eq' to 'M' +// No constructor could take the source type, or constructor overload +// resolution was ambiguous + +#if !defined _MSC_VER + +// The below ConvertibleFromAny struct is implicitly constructible from anything +// and when in the same namespace can interact with other tests. In particular, +// if it is in the same namespace as other tests and one removes +// NonImplicitlyConstructibleTypeWithOperatorEq::operator==(int lhs, ...); +// then the corresponding test still compiles (and it should not!) by implicitly +// converting NonImplicitlyConstructibleTypeWithOperatorEq to ConvertibleFromAny +// in m3.Matcher(). +namespace convertible_from_any { // Implicitly convertible from any type. struct ConvertibleFromAny { ConvertibleFromAny(int a_value) : value(a_value) {} template <typename T> - explicit ConvertibleFromAny(const T& /*a_value*/) : value(-1) { + ConvertibleFromAny(const T& /*a_value*/) : value(-1) { ADD_FAILURE() << "Conversion constructor called"; } int value; @@ -639,6 +787,9 @@ TEST(MatcherCastTest, FromConvertibleFromAny) { EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); } +} // namespace convertible_from_any + +#endif // !defined _MSC_VER struct IntReferenceWrapper { IntReferenceWrapper(const int& a_value) : value(&a_value) {} @@ -744,6 +895,9 @@ TEST(SafeMatcherCastTest, FromSameType) { EXPECT_FALSE(m2.Matches(1)); } +#if !defined _MSC_VER + +namespace convertible_from_any { TEST(SafeMatcherCastTest, ConversionConstructorIsUsed) { Matcher<ConvertibleFromAny> m = SafeMatcherCast<ConvertibleFromAny>(1); EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); @@ -756,6 +910,9 @@ TEST(SafeMatcherCastTest, FromConvertibleFromAny) { EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); } +} // namespace convertible_from_any + +#endif // !defined _MSC_VER TEST(SafeMatcherCastTest, ValueIsNotCopied) { int n = 42; @@ -767,7 +924,7 @@ TEST(SafeMatcherCastTest, ValueIsNotCopied) { TEST(ExpectThat, TakesLiterals) { EXPECT_THAT(1, 1); EXPECT_THAT(1.0, 1.0); - EXPECT_THAT(string(), ""); + EXPECT_THAT(std::string(), ""); } TEST(ExpectThat, TakesFunctions) { @@ -867,15 +1024,11 @@ class Unprintable { public: Unprintable() : c_('a') {} + bool operator==(const Unprintable& /* rhs */) const { return true; } private: char c_; }; -inline bool operator==(const Unprintable& /* lhs */, - const Unprintable& /* rhs */) { - return true; -} - TEST(EqTest, CanDescribeSelf) { Matcher<Unprintable> m = Eq(Unprintable()); EXPECT_EQ("is equal to 1-byte object <61>", Describe(m)); @@ -1046,14 +1199,14 @@ TEST(IsNullTest, ReferenceToConstLinkedPtr) { EXPECT_FALSE(m.Matches(non_null_p)); } -#if GTEST_HAS_STD_FUNCTION_ +#if GTEST_LANG_CXX11 TEST(IsNullTest, StdFunction) { const Matcher<std::function<void()>> m = IsNull(); EXPECT_TRUE(m.Matches(std::function<void()>())); EXPECT_FALSE(m.Matches([]{})); } -#endif // GTEST_HAS_STD_FUNCTION_ +#endif // GTEST_LANG_CXX11 // Tests that IsNull() describes itself properly. TEST(IsNullTest, CanDescribeSelf) { @@ -1094,14 +1247,14 @@ TEST(NotNullTest, ReferenceToConstLinkedPtr) { EXPECT_TRUE(m.Matches(non_null_p)); } -#if GTEST_HAS_STD_FUNCTION_ +#if GTEST_LANG_CXX11 TEST(NotNullTest, StdFunction) { const Matcher<std::function<void()>> m = NotNull(); EXPECT_TRUE(m.Matches([]{})); EXPECT_FALSE(m.Matches(std::function<void()>())); } -#endif // GTEST_HAS_STD_FUNCTION_ +#endif // GTEST_LANG_CXX11 // Tests that NotNull() describes itself properly. TEST(NotNullTest, CanDescribeSelf) { @@ -1177,6 +1330,13 @@ TEST(StrEqTest, MatchesEqualString) { Matcher<const std::string&> m2 = StrEq("Hello"); EXPECT_TRUE(m2.Matches("Hello")); EXPECT_FALSE(m2.Matches("Hi")); + +#if GTEST_HAS_ABSL + Matcher<const absl::string_view&> m3 = StrEq("Hello"); + EXPECT_TRUE(m3.Matches(absl::string_view("Hello"))); + EXPECT_FALSE(m3.Matches(absl::string_view("hello"))); + EXPECT_FALSE(m3.Matches(absl::string_view())); +#endif // GTEST_HAS_ABSL } TEST(StrEqTest, CanDescribeSelf) { @@ -1202,6 +1362,13 @@ TEST(StrNeTest, MatchesUnequalString) { Matcher<std::string> m2 = StrNe(std::string("Hello")); EXPECT_TRUE(m2.Matches("hello")); EXPECT_FALSE(m2.Matches("Hello")); + +#if GTEST_HAS_ABSL + Matcher<const absl::string_view> m3 = StrNe("Hello"); + EXPECT_TRUE(m3.Matches(absl::string_view(""))); + EXPECT_TRUE(m3.Matches(absl::string_view())); + EXPECT_FALSE(m3.Matches(absl::string_view("Hello"))); +#endif // GTEST_HAS_ABSL } TEST(StrNeTest, CanDescribeSelf) { @@ -1210,15 +1377,23 @@ TEST(StrNeTest, CanDescribeSelf) { } TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) { - Matcher<const char*> m = StrCaseEq(string("Hello")); + Matcher<const char*> m = StrCaseEq(std::string("Hello")); EXPECT_TRUE(m.Matches("Hello")); EXPECT_TRUE(m.Matches("hello")); EXPECT_FALSE(m.Matches("Hi")); EXPECT_FALSE(m.Matches(NULL)); - Matcher<const string&> m2 = StrCaseEq("Hello"); + Matcher<const std::string&> m2 = StrCaseEq("Hello"); EXPECT_TRUE(m2.Matches("hello")); EXPECT_FALSE(m2.Matches("Hi")); + +#if GTEST_HAS_ABSL + Matcher<const absl::string_view&> m3 = StrCaseEq(std::string("Hello")); + EXPECT_TRUE(m3.Matches(absl::string_view("Hello"))); + EXPECT_TRUE(m3.Matches(absl::string_view("hello"))); + EXPECT_FALSE(m3.Matches(absl::string_view("Hi"))); + EXPECT_FALSE(m3.Matches(absl::string_view())); +#endif // GTEST_HAS_ABSL } TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { @@ -1261,6 +1436,14 @@ TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) { Matcher<std::string> m2 = StrCaseNe(std::string("Hello")); EXPECT_TRUE(m2.Matches("")); EXPECT_FALSE(m2.Matches("Hello")); + +#if GTEST_HAS_ABSL + Matcher<const absl::string_view> m3 = StrCaseNe("Hello"); + EXPECT_TRUE(m3.Matches(absl::string_view("Hi"))); + EXPECT_TRUE(m3.Matches(absl::string_view())); + EXPECT_FALSE(m3.Matches(absl::string_view("Hello"))); + EXPECT_FALSE(m3.Matches(absl::string_view("hello"))); +#endif // GTEST_HAS_ABSL } TEST(StrCaseNeTest, CanDescribeSelf) { @@ -1292,6 +1475,25 @@ TEST(HasSubstrTest, WorksForCStrings) { EXPECT_FALSE(m2.Matches(NULL)); } +#if GTEST_HAS_ABSL +// Tests that HasSubstr() works for matching absl::string_view-typed values. +TEST(HasSubstrTest, WorksForStringViewClasses) { + const Matcher<absl::string_view> m1 = HasSubstr("foo"); + EXPECT_TRUE(m1.Matches(absl::string_view("I love food."))); + EXPECT_FALSE(m1.Matches(absl::string_view("tofo"))); + EXPECT_FALSE(m1.Matches(absl::string_view())); + + const Matcher<const absl::string_view&> m2 = HasSubstr("foo"); + EXPECT_TRUE(m2.Matches(absl::string_view("I love food."))); + EXPECT_FALSE(m2.Matches(absl::string_view("tofo"))); + EXPECT_FALSE(m2.Matches(absl::string_view())); + + const Matcher<const absl::string_view&> m3 = HasSubstr(""); + EXPECT_TRUE(m3.Matches(absl::string_view("foo"))); + EXPECT_FALSE(m3.Matches(absl::string_view())); +} +#endif // GTEST_HAS_ABSL + // Tests that HasSubstr(s) describes itself properly. TEST(HasSubstrTest, CanDescribeSelf) { Matcher<std::string> m = HasSubstr("foo\n\""); @@ -1320,6 +1522,35 @@ TEST(KeyTest, MatchesCorrectly) { EXPECT_THAT(p, Not(Key(Lt(25)))); } +#if GTEST_LANG_CXX11 +template <size_t I> +struct Tag {}; + +struct PairWithGet { + int member_1; + string member_2; + using first_type = int; + using second_type = string; + + const int& GetImpl(Tag<0>) const { return member_1; } + const string& GetImpl(Tag<1>) const { return member_2; } +}; +template <size_t I> +auto get(const PairWithGet& value) -> decltype(value.GetImpl(Tag<I>())) { + return value.GetImpl(Tag<I>()); +} +TEST(PairTest, MatchesPairWithGetCorrectly) { + PairWithGet 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)))); + + std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}}; + EXPECT_THAT(v, Contains(Key(29))); +} +#endif // GTEST_LANG_CXX11 + TEST(KeyTest, SafelyCastsInnerMatcher) { Matcher<int> is_positive = Gt(0); Matcher<int> is_negative = Lt(0); @@ -1423,7 +1654,7 @@ TEST(PairTest, MatchesCorrectly) { EXPECT_THAT(p, Pair(25, "foo")); EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o"))); - // 'first' does not match, but 'second' matches. + // 'first' doesnt' match, but 'second' matches. EXPECT_THAT(p, Not(Pair(42, "foo"))); EXPECT_THAT(p, Not(Pair(Lt(25), "foo"))); @@ -1457,6 +1688,18 @@ TEST(PairTest, InsideContainsUsingMap) { EXPECT_THAT(container, Not(Contains(Pair(3, _)))); } +#if GTEST_LANG_CXX11 +TEST(PairTest, UseGetInsteadOfMembers) { + PairWithGet pair{7, "ABC"}; + EXPECT_THAT(pair, Pair(7, "ABC")); + EXPECT_THAT(pair, Pair(Ge(7), HasSubstr("AB"))); + EXPECT_THAT(pair, Not(Pair(Lt(7), "ABC"))); + + std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}}; + EXPECT_THAT(v, ElementsAre(Pair(11, string("Foo")), Pair(Ge(10), Not("")))); +} +#endif // GTEST_LANG_CXX11 + // Tests StartsWith(s). TEST(StartsWithTest, MatchesStringWithGivenPrefix) { @@ -1486,12 +1729,30 @@ TEST(EndsWithTest, MatchesStringWithGivenSuffix) { EXPECT_TRUE(m1.Matches("")); EXPECT_FALSE(m1.Matches(NULL)); - const Matcher<const string&> m2 = EndsWith(string("Hi")); + const Matcher<const std::string&> m2 = EndsWith(std::string("Hi")); EXPECT_TRUE(m2.Matches("Hi")); EXPECT_TRUE(m2.Matches("Wow Hi Hi")); EXPECT_TRUE(m2.Matches("Super Hi")); EXPECT_FALSE(m2.Matches("i")); EXPECT_FALSE(m2.Matches("Hi ")); + +#if GTEST_HAS_GLOBAL_STRING + const Matcher<const ::string&> m3 = EndsWith(::string("Hi")); + EXPECT_TRUE(m3.Matches("Hi")); + EXPECT_TRUE(m3.Matches("Wow Hi Hi")); + EXPECT_TRUE(m3.Matches("Super Hi")); + EXPECT_FALSE(m3.Matches("i")); + EXPECT_FALSE(m3.Matches("Hi ")); +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_ABSL + const Matcher<const absl::string_view&> m4 = EndsWith(""); + EXPECT_TRUE(m4.Matches("Hi")); + EXPECT_TRUE(m4.Matches("")); + // Default-constructed absl::string_view should not match anything, in order + // to distinguish it from an empty string. + EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif // GTEST_HAS_ABSL } TEST(EndsWithTest, CanDescribeSelf) { @@ -1511,6 +1772,18 @@ TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) { EXPECT_TRUE(m2.Matches("azbz")); EXPECT_FALSE(m2.Matches("az1")); EXPECT_FALSE(m2.Matches("1az")); + +#if GTEST_HAS_ABSL + const Matcher<const absl::string_view&> m3 = MatchesRegex("a.*z"); + EXPECT_TRUE(m3.Matches(absl::string_view("az"))); + EXPECT_TRUE(m3.Matches(absl::string_view("abcz"))); + EXPECT_FALSE(m3.Matches(absl::string_view("1az"))); + // Default-constructed absl::string_view should not match anything, in order + // to distinguish it from an empty string. + EXPECT_FALSE(m3.Matches(absl::string_view())); + const Matcher<const absl::string_view&> m4 = MatchesRegex(""); + EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif // GTEST_HAS_ABSL } TEST(MatchesRegexTest, CanDescribeSelf) { @@ -1519,6 +1792,11 @@ TEST(MatchesRegexTest, CanDescribeSelf) { Matcher<const char*> m2 = MatchesRegex(new RE("a.*")); EXPECT_EQ("matches regular expression \"a.*\"", Describe(m2)); + +#if GTEST_HAS_ABSL + Matcher<const absl::string_view> m3 = MatchesRegex(new RE("0.*")); + EXPECT_EQ("matches regular expression \"0.*\"", Describe(m3)); +#endif // GTEST_HAS_ABSL } // Tests ContainsRegex(). @@ -1533,6 +1811,18 @@ TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) { EXPECT_TRUE(m2.Matches("azbz")); EXPECT_TRUE(m2.Matches("az1")); EXPECT_FALSE(m2.Matches("1a")); + +#if GTEST_HAS_ABSL + const Matcher<const absl::string_view&> m3 = ContainsRegex(new RE("a.*z")); + EXPECT_TRUE(m3.Matches(absl::string_view("azbz"))); + EXPECT_TRUE(m3.Matches(absl::string_view("az1"))); + EXPECT_FALSE(m3.Matches(absl::string_view("1a"))); + // Default-constructed absl::string_view should not match anything, in order + // to distinguish it from an empty string. + EXPECT_FALSE(m3.Matches(absl::string_view())); + const Matcher<const absl::string_view&> m4 = ContainsRegex(""); + EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif // GTEST_HAS_ABSL } TEST(ContainsRegexTest, CanDescribeSelf) { @@ -1541,6 +1831,11 @@ TEST(ContainsRegexTest, CanDescribeSelf) { Matcher<const char*> m2 = ContainsRegex(new RE("a.*")); EXPECT_EQ("contains regular expression \"a.*\"", Describe(m2)); + +#if GTEST_HAS_ABSL + Matcher<const absl::string_view> m3 = ContainsRegex(new RE("0.*")); + EXPECT_EQ("contains regular expression \"0.*\"", Describe(m3)); +#endif // GTEST_HAS_ABSL } // Tests for wide strings. @@ -2018,6 +2313,150 @@ TEST(Ne2Test, CanDescribeSelf) { EXPECT_EQ("are an unequal pair", Describe(m)); } +// Tests that FloatEq() matches a 2-tuple where +// FloatEq(first field) matches the second field. +TEST(FloatEq2Test, MatchesEqualArguments) { + typedef ::testing::tuple<float, float> Tpl; + Matcher<const Tpl&> m = FloatEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(0.3f, 0.1f + 0.1f + 0.1f))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); +} + +// Tests that FloatEq() describes itself properly. +TEST(FloatEq2Test, CanDescribeSelf) { + Matcher<const ::testing::tuple<float, float>&> m = FloatEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveFloatEq() matches a 2-tuple where +// NanSensitiveFloatEq(first field) matches the second field. +TEST(NanSensitiveFloatEqTest, MatchesEqualArgumentsWithNaN) { + typedef ::testing::tuple<float, float> Tpl; + Matcher<const Tpl&> m = NanSensitiveFloatEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), + std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveFloatEq() describes itself properly. +TEST(NanSensitiveFloatEqTest, CanDescribeSelfWithNaNs) { + Matcher<const ::testing::tuple<float, float>&> m = NanSensitiveFloatEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that DoubleEq() matches a 2-tuple where +// DoubleEq(first field) matches the second field. +TEST(DoubleEq2Test, MatchesEqualArguments) { + typedef ::testing::tuple<double, double> Tpl; + Matcher<const Tpl&> m = DoubleEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0, 1.0))); + EXPECT_TRUE(m.Matches(Tpl(0.3, 0.1 + 0.1 + 0.1))); + EXPECT_FALSE(m.Matches(Tpl(1.1, 1.0))); +} + +// Tests that DoubleEq() describes itself properly. +TEST(DoubleEq2Test, CanDescribeSelf) { + Matcher<const ::testing::tuple<double, double>&> m = DoubleEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveDoubleEq() matches a 2-tuple where +// NanSensitiveDoubleEq(first field) matches the second field. +TEST(NanSensitiveDoubleEqTest, MatchesEqualArgumentsWithNaN) { + typedef ::testing::tuple<double, double> Tpl; + Matcher<const Tpl&> m = NanSensitiveDoubleEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), + std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), 1.0f))); +} + +// Tests that DoubleEq() describes itself properly. +TEST(NanSensitiveDoubleEqTest, CanDescribeSelfWithNaNs) { + Matcher<const ::testing::tuple<double, double>&> m = NanSensitiveDoubleEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that FloatEq() matches a 2-tuple where +// FloatNear(first field, max_abs_error) matches the second field. +TEST(FloatNear2Test, MatchesEqualArguments) { + typedef ::testing::tuple<float, float> Tpl; + Matcher<const Tpl&> m = FloatNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.3f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.8f, 1.0f))); +} + +// Tests that FloatNear() describes itself properly. +TEST(FloatNear2Test, CanDescribeSelf) { + Matcher<const ::testing::tuple<float, float>&> m = FloatNear(0.5f); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveFloatNear() matches a 2-tuple where +// NanSensitiveFloatNear(first field) matches the second field. +TEST(NanSensitiveFloatNearTest, MatchesNearbyArgumentsWithNaN) { + typedef ::testing::tuple<float, float> Tpl; + Matcher<const Tpl&> m = NanSensitiveFloatNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), + std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.6f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveFloatNear() describes itself properly. +TEST(NanSensitiveFloatNearTest, CanDescribeSelfWithNaNs) { + Matcher<const ::testing::tuple<float, float>&> m = + NanSensitiveFloatNear(0.5f); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that FloatEq() matches a 2-tuple where +// DoubleNear(first field, max_abs_error) matches the second field. +TEST(DoubleNear2Test, MatchesEqualArguments) { + typedef ::testing::tuple<double, double> Tpl; + Matcher<const Tpl&> m = DoubleNear(0.5); + EXPECT_TRUE(m.Matches(Tpl(1.0, 1.0))); + EXPECT_TRUE(m.Matches(Tpl(1.3, 1.0))); + EXPECT_FALSE(m.Matches(Tpl(1.8, 1.0))); +} + +// Tests that DoubleNear() describes itself properly. +TEST(DoubleNear2Test, CanDescribeSelf) { + Matcher<const ::testing::tuple<double, double>&> m = DoubleNear(0.5); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveDoubleNear() matches a 2-tuple where +// NanSensitiveDoubleNear(first field) matches the second field. +TEST(NanSensitiveDoubleNearTest, MatchesNearbyArgumentsWithNaN) { + typedef ::testing::tuple<double, double> Tpl; + Matcher<const Tpl&> m = NanSensitiveDoubleNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), + std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.6f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveDoubleNear() describes itself properly. +TEST(NanSensitiveDoubleNearTest, CanDescribeSelfWithNaNs) { + Matcher<const ::testing::tuple<double, double>&> m = + NanSensitiveDoubleNear(0.5f); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + // Tests that Not(m) matches any value that doesn't match m. TEST(NotTest, NegatesMatcher) { Matcher<int> m; @@ -2106,7 +2545,7 @@ TEST(AllOfTest, VariadicMatchesWhenAllMatch) { ::testing::AllOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); Matcher<int> m = AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9), Ne(10), Ne(11)); - EXPECT_THAT(Describe(m), EndsWith("and (isn't equal to 11))))))))))")); + EXPECT_THAT(Describe(m), EndsWith("and (isn't equal to 11)")); AllOfMatches(11, m); AllOfMatches(50, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9), Ne(10), Ne(11), Ne(12), Ne(13), Ne(14), Ne(15), @@ -2300,7 +2739,7 @@ TEST(AnyOfTest, VariadicMatchesWhenAnyMatches) { // on ADL. Matcher<int> m = ::testing::AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); - EXPECT_THAT(Describe(m), EndsWith("or (is equal to 11))))))))))")); + EXPECT_THAT(Describe(m), EndsWith("or (is equal to 11)")); AnyOfMatches(11, m); AnyOfMatches(50, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, @@ -2309,6 +2748,33 @@ TEST(AnyOfTest, VariadicMatchesWhenAnyMatches) { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50)); } +// Tests the variadic version of the ElementsAreMatcher +TEST(ElementsAreTest, HugeMatcher) { + vector<int> test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + + EXPECT_THAT(test_vector, + ElementsAre(Eq(1), Eq(2), Lt(13), Eq(4), Eq(5), Eq(6), Eq(7), + Eq(8), Eq(9), Eq(10), Gt(1), Eq(12))); +} + +// Tests the variadic version of the UnorderedElementsAreMatcher +TEST(ElementsAreTest, HugeMatcherStr) { + vector<string> test_vector{ + "literal_string", "", "", "", "", "", "", "", "", "", "", ""}; + + EXPECT_THAT(test_vector, UnorderedElementsAre("literal_string", _, _, _, _, _, + _, _, _, _, _, _)); +} + +// Tests the variadic version of the UnorderedElementsAreMatcher +TEST(ElementsAreTest, HugeMatcherUnordered) { + vector<int> test_vector{2, 1, 8, 5, 4, 6, 7, 3, 9, 12, 11, 10}; + + EXPECT_THAT(test_vector, UnorderedElementsAre( + Eq(2), Eq(1), Gt(7), Eq(5), Eq(4), Eq(6), Eq(7), + Eq(3), Eq(9), Eq(12), Eq(11), Ne(122))); +} + #endif // GTEST_LANG_CXX11 // Tests that AnyOf(m1, ..., mn) describes itself properly. @@ -2583,6 +3049,22 @@ TEST(ExplainMatchResultTest, WorksInsideMATCHER) { EXPECT_THAT(0, Really(Eq(0))); } +TEST(DescribeMatcherTest, WorksWithValue) { + EXPECT_EQ("is equal to 42", DescribeMatcher<int>(42)); + EXPECT_EQ("isn't equal to 42", DescribeMatcher<int>(42, true)); +} + +TEST(DescribeMatcherTest, WorksWithMonomorphicMatcher) { + const Matcher<int> monomorphic = Le(0); + EXPECT_EQ("is <= 0", DescribeMatcher<int>(monomorphic)); + EXPECT_EQ("isn't <= 0", DescribeMatcher<int>(monomorphic, true)); +} + +TEST(DescribeMatcherTest, WorksWithPolymorphicMatcher) { + EXPECT_EQ("is even", DescribeMatcher<int>(PolymorphicIsEven())); + EXPECT_EQ("is odd", DescribeMatcher<int>(PolymorphicIsEven(), true)); +} + TEST(AllArgsTest, WorksForTuple) { EXPECT_THAT(make_tuple(1, 2L), AllArgs(Lt())); EXPECT_THAT(make_tuple(2L, 1), Not(AllArgs(Lt()))); @@ -2617,6 +3099,44 @@ TEST(AllArgsTest, WorksInWithClause) { EXPECT_EQ(2, helper.Helper('a', 1)); } +class OptionalMatchersHelper { + public: + OptionalMatchersHelper() {} + + MOCK_METHOD0(NoArgs, int()); + + MOCK_METHOD1(OneArg, int(int y)); + + MOCK_METHOD2(TwoArgs, int(char x, int y)); + + MOCK_METHOD1(Overloaded, int(char x)); + MOCK_METHOD2(Overloaded, int(char x, int y)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OptionalMatchersHelper); +}; + +TEST(AllArgsTest, WorksWithoutMatchers) { + OptionalMatchersHelper helper; + + ON_CALL(helper, NoArgs).WillByDefault(Return(10)); + ON_CALL(helper, OneArg).WillByDefault(Return(20)); + ON_CALL(helper, TwoArgs).WillByDefault(Return(30)); + + EXPECT_EQ(10, helper.NoArgs()); + EXPECT_EQ(20, helper.OneArg(1)); + EXPECT_EQ(30, helper.TwoArgs('\1', 2)); + + EXPECT_CALL(helper, NoArgs).Times(1); + EXPECT_CALL(helper, OneArg).WillOnce(Return(100)); + EXPECT_CALL(helper, OneArg(17)).WillOnce(Return(200)); + EXPECT_CALL(helper, TwoArgs).Times(0); + + EXPECT_EQ(10, helper.NoArgs()); + EXPECT_EQ(100, helper.OneArg(1)); + EXPECT_EQ(200, helper.OneArg(17)); +} + // Tests that ASSERT_THAT() and EXPECT_THAT() work when the value // matches the matcher. TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) { @@ -2712,18 +3232,22 @@ class FloatingPointTest : public testing::Test { zero_bits_(Floating(0).bits()), one_bits_(Floating(1).bits()), infinity_bits_(Floating(Floating::Infinity()).bits()), - close_to_positive_zero_(AsBits(zero_bits_ + max_ulps_/2)), - close_to_negative_zero_(AsBits(zero_bits_ + max_ulps_ - max_ulps_/2)), - further_from_negative_zero_(-AsBits( + close_to_positive_zero_( + Floating::ReinterpretBits(zero_bits_ + max_ulps_/2)), + close_to_negative_zero_( + -Floating::ReinterpretBits(zero_bits_ + max_ulps_ - max_ulps_/2)), + further_from_negative_zero_(-Floating::ReinterpretBits( zero_bits_ + max_ulps_ + 1 - max_ulps_/2)), - close_to_one_(AsBits(one_bits_ + max_ulps_)), - further_from_one_(AsBits(one_bits_ + max_ulps_ + 1)), + close_to_one_(Floating::ReinterpretBits(one_bits_ + max_ulps_)), + further_from_one_(Floating::ReinterpretBits(one_bits_ + max_ulps_ + 1)), infinity_(Floating::Infinity()), - close_to_infinity_(AsBits(infinity_bits_ - max_ulps_)), - further_from_infinity_(AsBits(infinity_bits_ - max_ulps_ - 1)), + close_to_infinity_( + Floating::ReinterpretBits(infinity_bits_ - max_ulps_)), + further_from_infinity_( + Floating::ReinterpretBits(infinity_bits_ - max_ulps_ - 1)), max_(Floating::Max()), - nan1_(AsBits(Floating::kExponentBitMask | 1)), - nan2_(AsBits(Floating::kExponentBitMask | 200)) { + nan1_(Floating::ReinterpretBits(Floating::kExponentBitMask | 1)), + nan2_(Floating::ReinterpretBits(Floating::kExponentBitMask | 200)) { } void TestSize() { @@ -2778,7 +3302,7 @@ class FloatingPointTest : public testing::Test { // Pre-calculated numbers to be used by the tests. - const size_t max_ulps_; + const Bits max_ulps_; const Bits zero_bits_; // The bits that represent 0.0. const Bits one_bits_; // The bits that represent 1.0. @@ -2804,12 +3328,6 @@ class FloatingPointTest : public testing::Test { // Some NaNs. const RawType nan1_; const RawType nan2_; - - private: - template <typename T> - static RawType AsBits(T value) { - return Floating::ReinterpretBits(static_cast<Bits>(value)); - } }; // Tests floating-point matchers with fixed epsilons. @@ -3186,8 +3704,6 @@ MATCHER_P(FieldIIs, inner_matcher, "") { return ExplainMatchResult(inner_matcher, arg.i, result_listener); } -#if GTEST_HAS_RTTI - TEST(WhenDynamicCastToTest, SameType) { Derived derived; derived.i = 4; @@ -3245,8 +3761,12 @@ TEST(WhenDynamicCastToTest, AmbiguousCast) { TEST(WhenDynamicCastToTest, Describe) { Matcher<Base*> matcher = WhenDynamicCastTo<Derived*>(Pointee(_)); - const string prefix = +#if GTEST_HAS_RTTI + const std::string prefix = "when dynamic_cast to " + internal::GetTypeName<Derived*>() + ", "; +#else // GTEST_HAS_RTTI + const std::string prefix = "when dynamic_cast, "; +#endif // GTEST_HAS_RTTI EXPECT_EQ(prefix + "points to a value that is anything", Describe(matcher)); EXPECT_EQ(prefix + "does not point to a value that is anything", DescribeNegation(matcher)); @@ -3280,8 +3800,6 @@ TEST(WhenDynamicCastToTest, BadReference) { EXPECT_THAT(as_base_ref, Not(WhenDynamicCastTo<const OtherDerived&>(_))); } -#endif // GTEST_HAS_RTTI - // Minimal const-propagating pointer. template <typename T> class ConstPropagatingPtr { @@ -3401,11 +3919,14 @@ struct DerivedStruct : public AStruct { // Tests that Field(&Foo::field, ...) works when field is non-const. TEST(FieldTest, WorksForNonConstField) { Matcher<AStruct> m = Field(&AStruct::x, Ge(0)); + Matcher<AStruct> m_with_name = Field("x", &AStruct::x, Ge(0)); AStruct a; EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.x = -1; EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } // Tests that Field(&Foo::field, ...) works when field is const. @@ -3413,9 +3934,13 @@ TEST(FieldTest, WorksForConstField) { AStruct a; Matcher<AStruct> m = Field(&AStruct::y, Ge(0.0)); + Matcher<AStruct> m_with_name = Field("y", &AStruct::y, Ge(0.0)); EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); m = Field(&AStruct::y, Le(0.0)); + m_with_name = Field("y", &AStruct::y, Le(0.0)); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } // Tests that Field(&Foo::field, ...) works when field is not copyable. @@ -3489,6 +4014,14 @@ TEST(FieldTest, CanDescribeSelf) { EXPECT_EQ("is an object whose given field isn't >= 0", DescribeNegation(m)); } +TEST(FieldTest, CanDescribeSelfWithFieldName) { + Matcher<const AStruct&> m = Field("field_name", &AStruct::x, Ge(0)); + + EXPECT_EQ("is an object whose field `field_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose field `field_name` isn't >= 0", + DescribeNegation(m)); +} + // Tests that Field() can explain the match result. TEST(FieldTest, CanExplainMatchResult) { Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); @@ -3503,6 +4036,19 @@ TEST(FieldTest, CanExplainMatchResult) { Explain(m, a)); } +TEST(FieldTest, CanExplainMatchResultWithFieldName) { + Matcher<const AStruct&> m = Field("field_name", &AStruct::x, Ge(0)); + + AStruct a; + a.x = 1; + EXPECT_EQ("whose field `field_name` is 1" + OfType("int"), Explain(m, a)); + + m = Field("field_name", &AStruct::x, GreaterThan(0)); + EXPECT_EQ("whose field `field_name` is 1" + OfType("int") + + ", which is 1 more than 0", + Explain(m, a)); +} + // Tests that Field() works when the argument is a pointer to const. TEST(FieldForPointerTest, WorksForPointerToConst) { Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); @@ -3560,6 +4106,14 @@ TEST(FieldForPointerTest, CanDescribeSelf) { EXPECT_EQ("is an object whose given field isn't >= 0", DescribeNegation(m)); } +TEST(FieldForPointerTest, CanDescribeSelfWithFieldName) { + Matcher<const AStruct*> m = Field("field_name", &AStruct::x, Ge(0)); + + EXPECT_EQ("is an object whose field `field_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose field `field_name` isn't >= 0", + DescribeNegation(m)); +} + // Tests that Field() can explain the result of matching a pointer. TEST(FieldForPointerTest, CanExplainMatchResult) { Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); @@ -3575,6 +4129,22 @@ TEST(FieldForPointerTest, CanExplainMatchResult) { ", which is 1 more than 0", Explain(m, &a)); } +TEST(FieldForPointerTest, CanExplainMatchResultWithFieldName) { + Matcher<const AStruct*> m = Field("field_name", &AStruct::x, Ge(0)); + + AStruct a; + a.x = 1; + EXPECT_EQ("", Explain(m, static_cast<const AStruct*>(NULL))); + EXPECT_EQ( + "which points to an object whose field `field_name` is 1" + OfType("int"), + Explain(m, &a)); + + m = Field("field_name", &AStruct::x, GreaterThan(0)); + EXPECT_EQ("which points to an object whose field `field_name` is 1" + + OfType("int") + ", which is 1 more than 0", + Explain(m, &a)); +} + // A user-defined class for testing Property(). class AClass { public: @@ -3618,26 +4188,33 @@ class DerivedClass : public AClass { // returns a non-reference. TEST(PropertyTest, WorksForNonReferenceProperty) { Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); + Matcher<const AClass&> m_with_name = Property("n", &AClass::n, Ge(0)); AClass a; a.set_n(1); EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.set_n(-1); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } // Tests that Property(&Foo::property, ...) works when property() // returns a reference to const. TEST(PropertyTest, WorksForReferenceToConstProperty) { Matcher<const AClass&> m = Property(&AClass::s, StartsWith("hi")); + Matcher<const AClass&> m_with_name = + Property("s", &AClass::s, StartsWith("hi")); AClass a; a.set_s("hill"); EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.set_s("hole"); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } #if GTEST_LANG_CXX11 @@ -3703,10 +4280,15 @@ TEST(PropertyTest, WorksForCompatibleMatcherType) { Matcher<const AClass&> m = Property(&AClass::n, Matcher<signed char>(Ge(0))); + Matcher<const AClass&> m_with_name = + Property("n", &AClass::n, Matcher<signed char>(Ge(0))); + AClass a; EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.set_n(-1); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } // Tests that Property() can describe itself. @@ -3718,6 +4300,14 @@ TEST(PropertyTest, CanDescribeSelf) { DescribeNegation(m)); } +TEST(PropertyTest, CanDescribeSelfWithPropertyName) { + Matcher<const AClass&> m = Property("fancy_name", &AClass::n, Ge(0)); + + EXPECT_EQ("is an object whose property `fancy_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose property `fancy_name` isn't >= 0", + DescribeNegation(m)); +} + // Tests that Property() can explain the match result. TEST(PropertyTest, CanExplainMatchResult) { Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); @@ -3732,6 +4322,19 @@ TEST(PropertyTest, CanExplainMatchResult) { Explain(m, a)); } +TEST(PropertyTest, CanExplainMatchResultWithPropertyName) { + Matcher<const AClass&> m = Property("fancy_name", &AClass::n, Ge(0)); + + AClass a; + a.set_n(1); + EXPECT_EQ("whose property `fancy_name` is 1" + OfType("int"), Explain(m, a)); + + m = Property("fancy_name", &AClass::n, GreaterThan(0)); + EXPECT_EQ("whose property `fancy_name` is 1" + OfType("int") + + ", which is 1 more than 0", + Explain(m, a)); +} + // Tests that Property() works when the argument is a pointer to const. TEST(PropertyForPointerTest, WorksForPointerToConst) { Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); @@ -3799,6 +4402,14 @@ TEST(PropertyForPointerTest, CanDescribeSelf) { DescribeNegation(m)); } +TEST(PropertyForPointerTest, CanDescribeSelfWithPropertyDescription) { + Matcher<const AClass*> m = Property("fancy_name", &AClass::n, Ge(0)); + + EXPECT_EQ("is an object whose property `fancy_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose property `fancy_name` isn't >= 0", + DescribeNegation(m)); +} + // Tests that Property() can explain the result of matching a pointer. TEST(PropertyForPointerTest, CanExplainMatchResult) { Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); @@ -3816,6 +4427,22 @@ TEST(PropertyForPointerTest, CanExplainMatchResult) { Explain(m, &a)); } +TEST(PropertyForPointerTest, CanExplainMatchResultWithPropertyName) { + Matcher<const AClass*> m = Property("fancy_name", &AClass::n, Ge(0)); + + AClass a; + a.set_n(1); + EXPECT_EQ("", Explain(m, static_cast<const AClass*>(NULL))); + EXPECT_EQ("which points to an object whose property `fancy_name` is 1" + + OfType("int"), + Explain(m, &a)); + + m = Property("fancy_name", &AClass::n, GreaterThan(0)); + EXPECT_EQ("which points to an object whose property `fancy_name` is 1" + + OfType("int") + ", which is 1 more than 0", + Explain(m, &a)); +} + // Tests ResultOf. // Tests that ResultOf(f, ...) compiles and works as expected when f is a @@ -3931,11 +4558,8 @@ TEST(ResultOfTest, WorksForFunctionReferences) { // Tests that ResultOf(f, ...) compiles and works as expected when f is a // function object. -struct Functor { - typedef std::string result_type; - typedef int argument_type; - - std::string operator()(int input) const { +struct Functor : public ::std::unary_function<int, std::string> { + result_type operator()(argument_type input) const { return IntToStringFunction(input); } }; @@ -4129,6 +4753,44 @@ TEST(IsEmptyTest, ExplainsResult) { EXPECT_EQ("whose size is 1", Explain(m, container)); } +TEST(IsTrueTest, IsTrueIsFalse) { + EXPECT_THAT(true, IsTrue()); + EXPECT_THAT(false, IsFalse()); + EXPECT_THAT(true, Not(IsFalse())); + EXPECT_THAT(false, Not(IsTrue())); + EXPECT_THAT(0, Not(IsTrue())); + EXPECT_THAT(0, IsFalse()); + EXPECT_THAT(NULL, Not(IsTrue())); + EXPECT_THAT(NULL, IsFalse()); + EXPECT_THAT(-1, IsTrue()); + EXPECT_THAT(-1, Not(IsFalse())); + EXPECT_THAT(1, IsTrue()); + EXPECT_THAT(1, Not(IsFalse())); + EXPECT_THAT(2, IsTrue()); + EXPECT_THAT(2, Not(IsFalse())); + int a = 42; + EXPECT_THAT(a, IsTrue()); + EXPECT_THAT(a, Not(IsFalse())); + EXPECT_THAT(&a, IsTrue()); + EXPECT_THAT(&a, Not(IsFalse())); + EXPECT_THAT(false, Not(IsTrue())); + EXPECT_THAT(true, Not(IsFalse())); +#if GTEST_LANG_CXX11 + EXPECT_THAT(std::true_type(), IsTrue()); + EXPECT_THAT(std::true_type(), Not(IsFalse())); + EXPECT_THAT(std::false_type(), IsFalse()); + EXPECT_THAT(std::false_type(), Not(IsTrue())); + EXPECT_THAT(nullptr, Not(IsTrue())); + EXPECT_THAT(nullptr, IsFalse()); + std::unique_ptr<int> null_unique; + std::unique_ptr<int> nonnull_unique(new int(0)); + EXPECT_THAT(null_unique, Not(IsTrue())); + EXPECT_THAT(null_unique, IsFalse()); + EXPECT_THAT(nonnull_unique, IsTrue()); + EXPECT_THAT(nonnull_unique, Not(IsFalse())); +#endif // GTEST_LANG_CXX11 +} + TEST(SizeIsTest, ImplementsSizeIs) { vector<int> container; EXPECT_THAT(container, SizeIs(0)); @@ -4683,6 +5345,250 @@ TEST(WhenSortedTest, WorksForVectorConstRefMatcherOnStreamlike) { EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3)))); } +TEST(IsSupersetOfTest, WorksForNativeArray) { + const int subset[] = {1, 4}; + const int superset[] = {1, 2, 4}; + const int disjoint[] = {1, 0, 3}; + EXPECT_THAT(subset, IsSupersetOf(subset)); + EXPECT_THAT(subset, Not(IsSupersetOf(superset))); + EXPECT_THAT(superset, IsSupersetOf(subset)); + EXPECT_THAT(subset, Not(IsSupersetOf(disjoint))); + EXPECT_THAT(disjoint, Not(IsSupersetOf(subset))); +} + +TEST(IsSupersetOfTest, WorksWithDuplicates) { + const int not_enough[] = {1, 2}; + const int enough[] = {1, 1, 2}; + const int expected[] = {1, 1}; + EXPECT_THAT(not_enough, Not(IsSupersetOf(expected))); + EXPECT_THAT(enough, IsSupersetOf(expected)); +} + +TEST(IsSupersetOfTest, WorksForEmpty) { + vector<int> numbers; + vector<int> expected; + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, Not(IsSupersetOf(expected))); + expected.clear(); + numbers.push_back(1); + numbers.push_back(2); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(2); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(3); + EXPECT_THAT(numbers, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, WorksForStreamlike) { + const int a[5] = {1, 2, 3, 4, 5}; + Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a)); + + vector<int> expected; + expected.push_back(1); + expected.push_back(2); + expected.push_back(5); + EXPECT_THAT(s, IsSupersetOf(expected)); + + expected.push_back(0); + EXPECT_THAT(s, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, TakesStlContainer) { + const int actual[] = {3, 1, 2}; + + ::std::list<int> expected; + expected.push_back(1); + expected.push_back(3); + EXPECT_THAT(actual, IsSupersetOf(expected)); + + expected.push_back(4); + EXPECT_THAT(actual, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, Describe) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + Describe<IntVec>(IsSupersetOf(expected)), + Eq("a surjection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSupersetOfTest, DescribeNegation) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + DescribeNegation<IntVec>(IsSupersetOf(expected)), + Eq("no surjection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSupersetOfTest, MatchAndExplain) { + std::vector<int> v; + v.push_back(2); + v.push_back(3); + std::vector<int> expected; + expected.push_back(1); + expected.push_back(2); + StringMatchResultListener listener; + ASSERT_FALSE(ExplainMatchResult(IsSupersetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), + Eq("where the following matchers don't match any elements:\n" + "matcher #0: is equal to 1")); + + v.push_back(1); + listener.Clear(); + ASSERT_TRUE(ExplainMatchResult(IsSupersetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), Eq("where:\n" + " - element #0 is matched by matcher #1,\n" + " - element #2 is matched by matcher #0")); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +TEST(IsSupersetOfTest, WorksForRhsInitializerList) { + const int numbers[] = {1, 3, 6, 2, 4, 5}; + EXPECT_THAT(numbers, IsSupersetOf({1, 2})); + EXPECT_THAT(numbers, Not(IsSupersetOf({3, 0}))); +} +#endif + +TEST(IsSubsetOfTest, WorksForNativeArray) { + const int subset[] = {1, 4}; + const int superset[] = {1, 2, 4}; + const int disjoint[] = {1, 0, 3}; + EXPECT_THAT(subset, IsSubsetOf(subset)); + EXPECT_THAT(subset, IsSubsetOf(superset)); + EXPECT_THAT(superset, Not(IsSubsetOf(subset))); + EXPECT_THAT(subset, Not(IsSubsetOf(disjoint))); + EXPECT_THAT(disjoint, Not(IsSubsetOf(subset))); +} + +TEST(IsSubsetOfTest, WorksWithDuplicates) { + const int not_enough[] = {1, 2}; + const int enough[] = {1, 1, 2}; + const int actual[] = {1, 1}; + EXPECT_THAT(actual, Not(IsSubsetOf(not_enough))); + EXPECT_THAT(actual, IsSubsetOf(enough)); +} + +TEST(IsSubsetOfTest, WorksForEmpty) { + vector<int> numbers; + vector<int> expected; + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.clear(); + numbers.push_back(1); + numbers.push_back(2); + EXPECT_THAT(numbers, Not(IsSubsetOf(expected))); + expected.push_back(1); + EXPECT_THAT(numbers, Not(IsSubsetOf(expected))); + expected.push_back(2); + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.push_back(3); + EXPECT_THAT(numbers, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, WorksForStreamlike) { + const int a[5] = {1, 2}; + Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a)); + + vector<int> expected; + expected.push_back(1); + EXPECT_THAT(s, Not(IsSubsetOf(expected))); + expected.push_back(2); + expected.push_back(5); + EXPECT_THAT(s, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, TakesStlContainer) { + const int actual[] = {3, 1, 2}; + + ::std::list<int> expected; + expected.push_back(1); + expected.push_back(3); + EXPECT_THAT(actual, Not(IsSubsetOf(expected))); + + expected.push_back(2); + expected.push_back(4); + EXPECT_THAT(actual, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, Describe) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + + EXPECT_THAT( + Describe<IntVec>(IsSubsetOf(expected)), + Eq("an injection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSubsetOfTest, DescribeNegation) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + DescribeNegation<IntVec>(IsSubsetOf(expected)), + Eq("no injection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSubsetOfTest, MatchAndExplain) { + std::vector<int> v; + v.push_back(2); + v.push_back(3); + std::vector<int> expected; + expected.push_back(1); + expected.push_back(2); + StringMatchResultListener listener; + ASSERT_FALSE(ExplainMatchResult(IsSubsetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), + Eq("where the following elements don't match any matchers:\n" + "element #1: 3")); + + expected.push_back(3); + listener.Clear(); + ASSERT_TRUE(ExplainMatchResult(IsSubsetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), Eq("where:\n" + " - element #0 is matched by matcher #1,\n" + " - element #1 is matched by matcher #2")); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +TEST(IsSubsetOfTest, WorksForRhsInitializerList) { + const int numbers[] = {1, 2, 3}; + EXPECT_THAT(numbers, IsSubsetOf({1, 2, 3, 4})); + EXPECT_THAT(numbers, Not(IsSubsetOf({1, 2}))); +} +#endif + // Tests using ElementsAre() and ElementsAreArray() with stream-like // "containers". @@ -5490,6 +6396,16 @@ TEST(PointwiseTest, WorksForRhsNativeArray) { EXPECT_THAT(lhs, Not(Pointwise(Lt(), rhs))); } +// Test is effective only with sanitizers. +TEST(PointwiseTest, WorksForVectorOfBool) { + vector<bool> rhs(3, false); + rhs[1] = true; + vector<bool> lhs = rhs; + EXPECT_THAT(lhs, Pointwise(Eq(), rhs)); + rhs[0] = true; + EXPECT_THAT(lhs, Not(Pointwise(Eq(), rhs))); +} + #if GTEST_HAS_STD_INITIALIZER_LIST_ TEST(PointwiseTest, WorksForRhsInitializerList) { @@ -5655,6 +6571,51 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) { EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs)); } +// Sample optional type implementation with minimal requirements for use with +// Optional matcher. +class SampleOptionalInt { + 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_; + } + private: + int value_; + bool has_value_; +}; + +TEST(OptionalTest, DescribesSelf) { + const Matcher<SampleOptionalInt> 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))); +} + +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); + 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; + EXPECT_FALSE(m.Matches(empty)); +} + class SampleVariantIntString { public: SampleVariantIntString(int i) : i_(i), has_int_(true) {} @@ -5719,5 +6680,90 @@ TEST(VariantTest, InnerDoesNotMatch) { EXPECT_FALSE(m.Matches(SampleVariantIntString("2"))); } +class SampleAnyType { + public: + explicit SampleAnyType(int i) : index_(0), i_(i) {} + explicit SampleAnyType(const std::string& s) : index_(1), s_(s) {} + + template <typename T> + friend const T* any_cast(const SampleAnyType* any) { + return any->get_impl(static_cast<T*>(NULL)); + } + + private: + int index_; + int i_; + std::string s_; + + const int* get_impl(int*) const { return index_ == 0 ? &i_ : NULL; } + const std::string* get_impl(std::string*) const { + return index_ == 1 ? &s_ : NULL; + } +}; + +TEST(AnyWithTest, FullMatch) { + Matcher<SampleAnyType> m = AnyWith<int>(Eq(1)); + EXPECT_TRUE(m.Matches(SampleAnyType(1))); +} + +TEST(AnyWithTest, TestBadCastType) { + Matcher<SampleAnyType> m = AnyWith<std::string>(Eq("fail")); + EXPECT_FALSE(m.Matches(SampleAnyType(1))); +} + +#if GTEST_LANG_CXX11 +TEST(AnyWithTest, TestUseInContainers) { + std::vector<SampleAnyType> a; + a.emplace_back(1); + a.emplace_back(2); + a.emplace_back(3); + EXPECT_THAT( + a, ElementsAreArray({AnyWith<int>(1), AnyWith<int>(2), AnyWith<int>(3)})); + + std::vector<SampleAnyType> b; + b.emplace_back("hello"); + b.emplace_back("merhaba"); + b.emplace_back("salut"); + EXPECT_THAT(b, ElementsAreArray({AnyWith<std::string>("hello"), + AnyWith<std::string>("merhaba"), + AnyWith<std::string>("salut")})); +} +#endif // GTEST_LANG_CXX11 +TEST(AnyWithTest, TestCompare) { + EXPECT_THAT(SampleAnyType(1), AnyWith<int>(Gt(0))); +} + +TEST(AnyWithTest, DescribesSelf) { + const Matcher<const SampleAnyType&> m = AnyWith<int>(Eq(1)); + EXPECT_THAT(Describe(m), ContainsRegex("is an 'any' type with value of type " + "'.*' and the value is equal to 1")); +} + +TEST(AnyWithTest, ExplainsSelf) { + const Matcher<const SampleAnyType&> m = AnyWith<int>(Eq(1)); + + EXPECT_THAT(Explain(m, SampleAnyType(1)), ContainsRegex("whose value 1")); + EXPECT_THAT(Explain(m, SampleAnyType("A")), + HasSubstr("whose value is not of type '")); + EXPECT_THAT(Explain(m, SampleAnyType(2)), "whose value 2 doesn't match"); +} + +#if GTEST_LANG_CXX11 + +TEST(PointeeTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, Pointee(Eq(3))); + EXPECT_THAT(p, Not(Pointee(Eq(2)))); +} + +TEST(NotTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, Pointee(Eq(3))); + EXPECT_THAT(p, Not(Pointee(Eq(2)))); +} + +#endif // GTEST_LANG_CXX11 + } // namespace gmock_matchers_test } // namespace testing + diff --git a/googlemock/test/gmock-more-actions_test.cc b/googlemock/test/gmock-more-actions_test.cc index f5e28eae..b13518aa 100644 --- a/googlemock/test/gmock-more-actions_test.cc +++ b/googlemock/test/gmock-more-actions_test.cc @@ -327,11 +327,10 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) { // Tests using Invoke() with functions with parameters declared as Unused. TEST(InvokeTest, FunctionWithUnusedParameters) { - Action<int(int, int, double, const string&)> a1 = - Invoke(SumOfFirst2); - string s("hi"); - EXPECT_EQ(12, a1.Perform( - tuple<int, int, double, const string&>(10, 2, 5.6, s))); + Action<int(int, int, double, const std::string&)> a1 = Invoke(SumOfFirst2); + tuple<int, int, double, std::string> dummy = + make_tuple(10, 2, 5.6, std::string("hi")); + EXPECT_EQ(12, a1.Perform(dummy)); Action<int(int, int, bool, int*)> a2 = Invoke(SumOfFirst2); @@ -380,10 +379,10 @@ TEST(InvokeMethodTest, Unary) { // Tests using Invoke() with a binary method. TEST(InvokeMethodTest, Binary) { Foo foo; - Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary); - string s("Hell"); - EXPECT_EQ("Hello", a.Perform( - tuple<const string&, char>(s, 'o'))); + Action<std::string(const std::string&, char)> a = Invoke(&foo, &Foo::Binary); + std::string s("Hell"); + tuple<std::string, char> dummy = make_tuple(s, 'o'); + EXPECT_EQ("Hello", a.Perform(dummy)); } // Tests using Invoke() with a ternary method. diff --git a/googlemock/test/gmock-nice-strict_test.cc b/googlemock/test/gmock-nice-strict_test.cc index 0eac6439..c4194946 100644 --- a/googlemock/test/gmock-nice-strict_test.cc +++ b/googlemock/test/gmock-nice-strict_test.cc @@ -32,9 +32,10 @@ #include "gmock/gmock-generated-nice-strict.h" #include <string> +#include <utility> #include "gmock/gmock.h" -#include "gtest/gtest.h" #include "gtest/gtest-spi.h" +#include "gtest/gtest.h" // This must not be defined inside the ::testing namespace, or it will // clash with ::testing::Mock. @@ -114,6 +115,24 @@ class MockBar { GTEST_DISALLOW_COPY_AND_ASSIGN_(MockBar); }; +#if GTEST_GTEST_LANG_CXX11 + +class MockBaz { + public: + class MoveOnly { + MoveOnly() = default; + + MoveOnly(const MoveOnly&) = delete; + operator=(const MoveOnly&) = delete; + + MoveOnly(MoveOnly&&) = default; + operator=(MoveOnly&&) = default; + }; + + MockBaz(MoveOnly) {} +} +#endif // GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + #if GTEST_HAS_STREAM_REDIRECTION // Tests that a raw mock generates warnings for uninteresting calls. @@ -214,8 +233,9 @@ TEST(NiceMockTest, AllowsExpectedCall) { nice_foo.DoThis(); } -// Tests that an unexpected call on a nice mock which returns a not-default-constructible -// type throws an exception and the exception contains the method's name. +// Tests that an unexpected call on a nice mock which returns a +// not-default-constructible type throws an exception and the exception contains +// the method's name. TEST(NiceMockTest, ThrowsExceptionForUnknownReturnTypes) { NiceMock<MockFoo> nice_foo; #if GTEST_HAS_EXCEPTIONS @@ -259,6 +279,21 @@ TEST(NiceMockTest, NonDefaultConstructor10) { nice_bar.That(5, true); } +TEST(NiceMockTest, AllowLeak) { + NiceMock<MockFoo>* leaked = new NiceMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + +TEST(NiceMockTest, MoveOnlyConstructor) { + NiceMock<MockBaz> nice_baz(MockBaz::MoveOnly()); +} + +#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that NiceMock<Mock> compiles where Mock is a user-defined // class (as opposed to ::testing::Mock). We had to work around an @@ -352,6 +387,21 @@ TEST(NaggyMockTest, NonDefaultConstructor10) { naggy_bar.That(5, true); } +TEST(NaggyMockTest, AllowLeak) { + NaggyMock<MockFoo>* leaked = new NaggyMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + +TEST(NaggyMockTest, MoveOnlyConstructor) { + NaggyMock<MockBaz> naggy_baz(MockBaz::MoveOnly()); +} + +#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that NaggyMock<Mock> compiles where Mock is a user-defined // class (as opposed to ::testing::Mock). We had to work around an @@ -426,6 +476,21 @@ TEST(StrictMockTest, NonDefaultConstructor10) { "Uninteresting mock function call"); } +TEST(StrictMockTest, AllowLeak) { + StrictMock<MockFoo>* leaked = new StrictMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + +TEST(StrictMockTest, MoveOnlyConstructor) { + StrictMock<MockBaz> strict_baz(MockBaz::MoveOnly()); +} + +#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that StrictMock<Mock> compiles where Mock is a user-defined // class (as opposed to ::testing::Mock). We had to work around an diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc index a7bf03e5..715aac8c 100644 --- a/googlemock/test/gmock-spec-builders_test.cc +++ b/googlemock/test/gmock-spec-builders_test.cc @@ -89,6 +89,7 @@ using testing::Mock; using testing::NaggyMock; using testing::Ne; using testing::Return; +using testing::SaveArg; using testing::Sequence; using testing::SetArgPointee; using testing::internal::ExpectationTester; @@ -748,7 +749,6 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) { testing::GMOCK_FLAG(default_mock_behavior) = original_behavior; } - #endif // GTEST_HAS_STREAM_REDIRECTION // Tests the semantics of ON_CALL(). @@ -2174,7 +2174,9 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture { "NOTE: You can safely ignore the above warning unless this " "call should not happen. Do not suppress it by blindly adding " "an EXPECT_CALL() if you don't mean to enforce the call. " - "See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#" + "See " + "https://github.com/google/googletest/blob/master/googlemock/docs/" + "CookBook.md#" "knowing-when-to-expect for details."; // A void-returning function. @@ -2680,6 +2682,75 @@ TEST(SynchronizationTest, CanCallMockMethodInAction) { // EXPECT_CALL() did not specify an action. } +TEST(ParameterlessExpectationsTest, CanSetExpectationsWithoutMatchers) { + MockA a; + int do_a_arg0 = 0; + ON_CALL(a, DoA).WillByDefault(SaveArg<0>(&do_a_arg0)); + int do_a_47_arg0 = 0; + ON_CALL(a, DoA(47)).WillByDefault(SaveArg<0>(&do_a_47_arg0)); + + a.DoA(17); + EXPECT_THAT(do_a_arg0, 17); + EXPECT_THAT(do_a_47_arg0, 0); + a.DoA(47); + EXPECT_THAT(do_a_arg0, 17); + EXPECT_THAT(do_a_47_arg0, 47); + + ON_CALL(a, Binary).WillByDefault(Return(true)); + ON_CALL(a, Binary(_, 14)).WillByDefault(Return(false)); + EXPECT_THAT(a.Binary(14, 17), true); + EXPECT_THAT(a.Binary(17, 14), false); +} + +TEST(ParameterlessExpectationsTest, CanSetExpectationsForOverloadedMethods) { + MockB b; + ON_CALL(b, DoB()).WillByDefault(Return(9)); + ON_CALL(b, DoB(5)).WillByDefault(Return(11)); + + EXPECT_THAT(b.DoB(), 9); + EXPECT_THAT(b.DoB(1), 0); // default value + EXPECT_THAT(b.DoB(5), 11); +} + +struct MockWithConstMethods { + public: + MOCK_CONST_METHOD1(Foo, int(int)); + MOCK_CONST_METHOD2(Bar, int(int, const char*)); +}; + +TEST(ParameterlessExpectationsTest, CanSetExpectationsForConstMethods) { + MockWithConstMethods mock; + ON_CALL(mock, Foo).WillByDefault(Return(7)); + ON_CALL(mock, Bar).WillByDefault(Return(33)); + + EXPECT_THAT(mock.Foo(17), 7); + EXPECT_THAT(mock.Bar(27, "purple"), 33); +} + +class MockConstOverload { + public: + MOCK_METHOD1(Overloaded, int(int)); + MOCK_CONST_METHOD1(Overloaded, int(int)); +}; + +TEST(ParameterlessExpectationsTest, + CanSetExpectationsForConstOverloadedMethods) { + MockConstOverload mock; + ON_CALL(mock, Overloaded(_)).WillByDefault(Return(7)); + ON_CALL(mock, Overloaded(5)).WillByDefault(Return(9)); + ON_CALL(Const(mock), Overloaded(5)).WillByDefault(Return(11)); + ON_CALL(Const(mock), Overloaded(7)).WillByDefault(Return(13)); + + EXPECT_THAT(mock.Overloaded(1), 7); + EXPECT_THAT(mock.Overloaded(5), 9); + EXPECT_THAT(mock.Overloaded(7), 7); + + const MockConstOverload& const_mock = mock; + EXPECT_THAT(const_mock.Overloaded(1), 0); + EXPECT_THAT(const_mock.Overloaded(5), 11); + EXPECT_THAT(const_mock.Overloaded(7), 13); +} + } // namespace // Allows the user to define their own main and then invoke gmock_main @@ -2691,7 +2762,6 @@ int gmock_main(int argc, char **argv) { int main(int argc, char **argv) { #endif // GMOCK_RENAME_MAIN testing::InitGoogleMock(&argc, argv); - // Ensures that the tests pass no matter what value of // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies. testing::GMOCK_FLAG(catch_leaked_mocks) = true; diff --git a/googlemock/test/gmock_output_test_.cc b/googlemock/test/gmock_output_test_.cc index d80e2b08..1b59eb3f 100644 --- a/googlemock/test/gmock_output_test_.cc +++ b/googlemock/test/gmock_output_test_.cc @@ -39,6 +39,12 @@ #include "gtest/gtest.h" +// Silence C4100 (unreferenced formal parameter) +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + using testing::_; using testing::AnyNumber; using testing::Ge; @@ -273,6 +279,11 @@ MATCHER_P2(IsPair, first, second, "") { return Value(arg.first, first) && Value(arg.second, second); } +TEST_F(GMockOutputTest, PrintsMatcher) { + const testing::Matcher<int> m1 = Ge(48); + EXPECT_THAT((std::pair<int, bool>(42, true)), IsPair(m1, true)); +} + void TestCatchesLeakedMocksInAdHocTests() { MockFoo* foo = new MockFoo; @@ -293,3 +304,7 @@ int main(int argc, char **argv) { TestCatchesLeakedMocksInAdHocTests(); return RUN_ALL_TESTS(); } + +#ifdef _MSC_VER +# pragma warning(pop) +#endif diff --git a/googlemock/test/gmock_output_test_golden.txt b/googlemock/test/gmock_output_test_golden.txt index 689d5eeb..dbcb2118 100644 --- a/googlemock/test/gmock_output_test_golden.txt +++ b/googlemock/test/gmock_output_test_golden.txt @@ -288,6 +288,12 @@ Stack trace: [ OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction [ RUN ] GMockOutputTest.CatchesLeakedMocks [ OK ] GMockOutputTest.CatchesLeakedMocks +[ RUN ] GMockOutputTest.PrintsMatcher +FILE:#: Failure +Value of: (std::pair<int, bool>(42, true)) +Expected: is pair (is >= 48, true) + Actual: (42, true) (of type std::pair<int, bool>) +[ FAILED ] GMockOutputTest.PrintsMatcher [ FAILED ] GMockOutputTest.UnexpectedCall [ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction [ FAILED ] GMockOutputTest.ExcessiveCall @@ -302,9 +308,10 @@ Stack trace: [ FAILED ] GMockOutputTest.MismatchArgumentsAndWith [ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction [ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction +[ FAILED ] GMockOutputTest.PrintsMatcher FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. -ERROR: 3 leaked mock objects found at program exit. +ERROR: 3 leaked mock objects found at program exit. Expectations on a mock object is verified when the object is destructed. Leaking a mock means that its expectations aren't verified, which is usually a test bug. If you really intend to leak a mock, you can suppress this error using testing::Mock::AllowLeak(mock_object), or you may use a fake or stub instead of a mock. |