diff options
Diffstat (limited to 'googlemock')
| -rw-r--r-- | googlemock/test/gmock-actions_test.cc | 145 | 
1 files changed, 144 insertions, 1 deletions
| diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index 2cbf0ee3..08f2a559 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -74,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; @@ -714,6 +715,8 @@ class MockClass {    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: @@ -765,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; @@ -1420,8 +1423,148 @@ 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); +  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 | 
