"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "googlemock/test/gmock-actions_test.cc" between
googletest-release-1.10.0.tar.gz and googletest-release-1.11.0.tar.gz

About: GoogleTest is Google's (unit) testing and mocking framework for C++ tests.

gmock-actions_test.cc  (googletest-release-1.10.0):gmock-actions_test.cc  (googletest-release-1.11.0)
skipping to change at line 34 skipping to change at line 34
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
// This file tests the built-in actions. // This file tests the built-in actions.
// Silence C4800 (C4800: 'int *const ': forcing value // Silence C4100 (unreferenced formal parameter) for MSVC
// to bool 'true' or 'false') for MSVC 15
#ifdef _MSC_VER #ifdef _MSC_VER
#if _MSC_VER == 1900
# pragma warning(push) # pragma warning(push)
# pragma warning(disable:4100)
#if _MSC_VER == 1900
// and silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15
# pragma warning(disable:4800) # pragma warning(disable:4800)
#endif #endif
#endif #endif
#include "gmock/gmock-actions.h" #include "gmock/gmock-actions.h"
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <string> #include <string>
#include <type_traits>
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
namespace { namespace {
// This list should be kept sorted. using ::testing::_;
using testing::_; using ::testing::Action;
using testing::Action; using ::testing::ActionInterface;
using testing::ActionInterface; using ::testing::Assign;
using testing::Assign; using ::testing::ByMove;
using testing::ByMove; using ::testing::ByRef;
using testing::ByRef; using ::testing::DefaultValue;
using testing::DefaultValue; using ::testing::DoAll;
using testing::DoAll; using ::testing::DoDefault;
using testing::DoDefault; using ::testing::IgnoreResult;
using testing::IgnoreResult; using ::testing::Invoke;
using testing::Invoke; using ::testing::InvokeWithoutArgs;
using testing::InvokeWithoutArgs; using ::testing::MakePolymorphicAction;
using testing::MakePolymorphicAction; using ::testing::PolymorphicAction;
using testing::Ne; using ::testing::Return;
using testing::PolymorphicAction; using ::testing::ReturnNew;
using testing::Return; using ::testing::ReturnNull;
using testing::ReturnNull; using ::testing::ReturnRef;
using testing::ReturnRef; using ::testing::ReturnRefOfCopy;
using testing::ReturnRefOfCopy; using ::testing::ReturnRoundRobin;
using testing::SetArgPointee; using ::testing::SetArgPointee;
using testing::SetArgumentPointee; using ::testing::SetArgumentPointee;
using testing::Unused; using ::testing::Unused;
using testing::WithArgs; using ::testing::WithArgs;
using testing::internal::BuiltInDefaultValue; using ::testing::internal::BuiltInDefaultValue;
using testing::internal::Int64;
using testing::internal::UInt64;
#if !GTEST_OS_WINDOWS_MOBILE #if !GTEST_OS_WINDOWS_MOBILE
using testing::SetErrnoAndReturn; using ::testing::SetErrnoAndReturn;
#endif #endif
// Tests that BuiltInDefaultValue<T*>::Get() returns NULL. // Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) { TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) {
EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == nullptr); EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == nullptr);
EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == nullptr); EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == nullptr);
EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == nullptr); EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == nullptr);
} }
// Tests that BuiltInDefaultValue<T*>::Exists() return true. // Tests that BuiltInDefaultValue<T*>::Exists() return true.
skipping to change at line 123 skipping to change at line 124
#endif #endif
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned int>::Get()); EXPECT_EQ(0U, BuiltInDefaultValue<unsigned int>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<int>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<int>::Get());
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT
EXPECT_EQ(0U, BuiltInDefaultValue<UInt64>::Get()); EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<Int64>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<signed long long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<long long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<float>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<float>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<double>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<double>::Get());
} }
// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a // Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a
// built-in numeric type. // built-in numeric type.
TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) { TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) {
EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<char>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<char>::Exists());
skipping to change at line 147 skipping to change at line 149
#endif #endif
EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<signed short>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<signed short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<short>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<unsigned int>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<unsigned int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<signed int>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<signed int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<int>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<unsigned long>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<unsigned long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<signed long>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<signed long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<long>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<UInt64>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<unsigned long long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<Int64>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<signed long long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<long long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<float>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<float>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<double>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<double>::Exists());
} }
// Tests that BuiltInDefaultValue<bool>::Get() returns false. // Tests that BuiltInDefaultValue<bool>::Get() returns false.
TEST(BuiltInDefaultValueTest, IsFalseForBool) { TEST(BuiltInDefaultValueTest, IsFalseForBool) {
EXPECT_FALSE(BuiltInDefaultValue<bool>::Get()); EXPECT_FALSE(BuiltInDefaultValue<bool>::Get());
} }
// Tests that BuiltInDefaultValue<bool>::Exists() returns true. // Tests that BuiltInDefaultValue<bool>::Exists() returns true.
skipping to change at line 573 skipping to change at line 576
// when the action is cast to Action<T(...)> rather than when the action is // when the action is cast to Action<T(...)> rather than when the action is
// performed. See comments on testing::internal::ReturnAction in // performed. See comments on testing::internal::ReturnAction in
// gmock-actions.h for more information. // gmock-actions.h for more information.
class FromType { class FromType {
public: public:
explicit FromType(bool* is_converted) : converted_(is_converted) {} explicit FromType(bool* is_converted) : converted_(is_converted) {}
bool* converted() const { return converted_; } bool* converted() const { return converted_; }
private: private:
bool* const converted_; bool* const converted_;
GTEST_DISALLOW_ASSIGN_(FromType);
}; };
class ToType { class ToType {
public: public:
// Must allow implicit conversion due to use in ImplicitCast_<T>. // Must allow implicit conversion due to use in ImplicitCast_<T>.
ToType(const FromType& x) { *x.converted() = true; } // NOLINT ToType(const FromType& x) { *x.converted() = true; } // NOLINT
}; };
TEST(ReturnTest, ConvertsArgumentWhenConverted) { TEST(ReturnTest, ConvertsArgumentWhenConverted) {
bool converted = false; bool converted = false;
skipping to change at line 646 skipping to change at line 647
TEST(ReturnRefTest, IsCovariant) { TEST(ReturnRefTest, IsCovariant) {
Base base; Base base;
Derived derived; Derived derived;
Action<Base&()> a = ReturnRef(base); Action<Base&()> a = ReturnRef(base);
EXPECT_EQ(&base, &a.Perform(std::make_tuple())); EXPECT_EQ(&base, &a.Perform(std::make_tuple()));
a = ReturnRef(derived); a = ReturnRef(derived);
EXPECT_EQ(&derived, &a.Perform(std::make_tuple())); EXPECT_EQ(&derived, &a.Perform(std::make_tuple()));
} }
template <typename T, typename = decltype(ReturnRef(std::declval<T&&>()))>
bool CanCallReturnRef(T&&) { return true; }
bool CanCallReturnRef(Unused) { return false; }
// Tests that ReturnRef(v) is working with non-temporaries (T&)
TEST(ReturnRefTest, WorksForNonTemporary) {
int scalar_value = 123;
EXPECT_TRUE(CanCallReturnRef(scalar_value));
std::string non_scalar_value("ABC");
EXPECT_TRUE(CanCallReturnRef(non_scalar_value));
const int const_scalar_value{321};
EXPECT_TRUE(CanCallReturnRef(const_scalar_value));
const std::string const_non_scalar_value("CBA");
EXPECT_TRUE(CanCallReturnRef(const_non_scalar_value));
}
// Tests that ReturnRef(v) is not working with temporaries (T&&)
TEST(ReturnRefTest, DoesNotWorkForTemporary) {
auto scalar_value = []() -> int { return 123; };
EXPECT_FALSE(CanCallReturnRef(scalar_value()));
auto non_scalar_value = []() -> std::string { return "ABC"; };
EXPECT_FALSE(CanCallReturnRef(non_scalar_value()));
// cannot use here callable returning "const scalar type",
// because such const for scalar return type is ignored
EXPECT_FALSE(CanCallReturnRef(static_cast<const int>(321)));
auto const_non_scalar_value = []() -> const std::string { return "CBA"; };
EXPECT_FALSE(CanCallReturnRef(const_non_scalar_value()));
}
// Tests that ReturnRefOfCopy(v) works for reference types. // Tests that ReturnRefOfCopy(v) works for reference types.
TEST(ReturnRefOfCopyTest, WorksForReference) { TEST(ReturnRefOfCopyTest, WorksForReference) {
int n = 42; int n = 42;
const Action<const int&()> ret = ReturnRefOfCopy(n); const Action<const int&()> ret = ReturnRefOfCopy(n);
EXPECT_NE(&n, &ret.Perform(std::make_tuple())); EXPECT_NE(&n, &ret.Perform(std::make_tuple()));
EXPECT_EQ(42, ret.Perform(std::make_tuple())); EXPECT_EQ(42, ret.Perform(std::make_tuple()));
n = 43; n = 43;
EXPECT_NE(&n, &ret.Perform(std::make_tuple())); EXPECT_NE(&n, &ret.Perform(std::make_tuple()));
skipping to change at line 670 skipping to change at line 706
TEST(ReturnRefOfCopyTest, IsCovariant) { TEST(ReturnRefOfCopyTest, IsCovariant) {
Base base; Base base;
Derived derived; Derived derived;
Action<Base&()> a = ReturnRefOfCopy(base); Action<Base&()> a = ReturnRefOfCopy(base);
EXPECT_NE(&base, &a.Perform(std::make_tuple())); EXPECT_NE(&base, &a.Perform(std::make_tuple()));
a = ReturnRefOfCopy(derived); a = ReturnRefOfCopy(derived);
EXPECT_NE(&derived, &a.Perform(std::make_tuple())); EXPECT_NE(&derived, &a.Perform(std::make_tuple()));
} }
// Tests that ReturnRoundRobin(v) works with initializer lists
TEST(ReturnRoundRobinTest, WorksForInitList) {
Action<int()> ret = ReturnRoundRobin({1, 2, 3});
EXPECT_EQ(1, ret.Perform(std::make_tuple()));
EXPECT_EQ(2, ret.Perform(std::make_tuple()));
EXPECT_EQ(3, ret.Perform(std::make_tuple()));
EXPECT_EQ(1, ret.Perform(std::make_tuple()));
EXPECT_EQ(2, ret.Perform(std::make_tuple()));
EXPECT_EQ(3, ret.Perform(std::make_tuple()));
}
// Tests that ReturnRoundRobin(v) works with vectors
TEST(ReturnRoundRobinTest, WorksForVector) {
std::vector<double> v = {4.4, 5.5, 6.6};
Action<double()> ret = ReturnRoundRobin(v);
EXPECT_EQ(4.4, ret.Perform(std::make_tuple()));
EXPECT_EQ(5.5, ret.Perform(std::make_tuple()));
EXPECT_EQ(6.6, ret.Perform(std::make_tuple()));
EXPECT_EQ(4.4, ret.Perform(std::make_tuple()));
EXPECT_EQ(5.5, ret.Perform(std::make_tuple()));
EXPECT_EQ(6.6, ret.Perform(std::make_tuple()));
}
// Tests that DoDefault() does the default action for the mock method. // Tests that DoDefault() does the default action for the mock method.
class MockClass { class MockClass {
public: public:
MockClass() {} MockClass() {}
MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT
MOCK_METHOD0(Foo, MyNonDefaultConstructible()); MOCK_METHOD0(Foo, MyNonDefaultConstructible());
MOCK_METHOD0(MakeUnique, std::unique_ptr<int>()); MOCK_METHOD0(MakeUnique, std::unique_ptr<int>());
MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>()); MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>());
skipping to change at line 734 skipping to change at line 795
// Ideally we should verify the error message as well. Sadly, // Ideally we should verify the error message as well. Sadly,
// EXPECT_DEATH() can only capture stderr, while Google Mock's // EXPECT_DEATH() can only capture stderr, while Google Mock's
// errors are printed on stdout. Therefore we have to settle for // errors are printed on stdout. Therefore we have to settle for
// not verifying the message. // not verifying the message.
EXPECT_DEATH_IF_SUPPORTED({ EXPECT_DEATH_IF_SUPPORTED({
mock.IntFunc(true); mock.IntFunc(true);
}, ""); }, "");
} }
// Tests that DoDefault() returns the default value set by // Tests that DoDefault() returns the default value set by
// DefaultValue<T>::Set() when it's not overriden by an ON_CALL(). // DefaultValue<T>::Set() when it's not overridden by an ON_CALL().
TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
DefaultValue<int>::Set(1); DefaultValue<int>::Set(1);
MockClass mock; MockClass mock;
EXPECT_CALL(mock, IntFunc(_)) EXPECT_CALL(mock, IntFunc(_))
.WillOnce(DoDefault()); .WillOnce(DoDefault());
EXPECT_EQ(1, mock.IntFunc(false)); EXPECT_EQ(1, mock.IntFunc(false));
DefaultValue<int>::Clear(); DefaultValue<int>::Clear();
} }
// Tests that DoDefault() does the action specified by ON_CALL(). // Tests that DoDefault() does the action specified by ON_CALL().
skipping to change at line 1229 skipping to change at line 1290
// Tests that Google Mock prints expression ByRef(x) as a reference to x. // Tests that Google Mock prints expression ByRef(x) as a reference to x.
TEST(ByRefTest, PrintsCorrectly) { TEST(ByRefTest, PrintsCorrectly) {
int n = 42; int n = 42;
::std::stringstream expected, actual; ::std::stringstream expected, actual;
testing::internal::UniversalPrinter<const int&>::Print(n, &expected); testing::internal::UniversalPrinter<const int&>::Print(n, &expected);
testing::internal::UniversalPrint(ByRef(n), &actual); testing::internal::UniversalPrint(ByRef(n), &actual);
EXPECT_EQ(expected.str(), actual.str()); EXPECT_EQ(expected.str(), actual.str());
} }
struct UnaryConstructorClass {
explicit UnaryConstructorClass(int v) : value(v) {}
int value;
};
// Tests using ReturnNew() with a unary constructor.
TEST(ReturnNewTest, Unary) {
Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000);
UnaryConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(4000, c->value);
delete c;
}
TEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) {
Action<UnaryConstructorClass*(bool, int)> a =
ReturnNew<UnaryConstructorClass>(4000);
UnaryConstructorClass* c = a.Perform(std::make_tuple(false, 5));
EXPECT_EQ(4000, c->value);
delete c;
}
TEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) {
Action<const UnaryConstructorClass*()> a =
ReturnNew<UnaryConstructorClass>(4000);
const UnaryConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(4000, c->value);
delete c;
}
class TenArgConstructorClass {
public:
TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, int a6, int a7,
int a8, int a9, int a10)
: value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {}
int value_;
};
// Tests using ReturnNew() with a 10-argument constructor.
TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
Action<TenArgConstructorClass*()> a = ReturnNew<TenArgConstructorClass>(
1000000000, 200000000, 30000000, 4000000, 500000, 60000, 7000, 800, 90,
0);
TenArgConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(1234567890, c->value_);
delete c;
}
std::unique_ptr<int> UniquePtrSource() { std::unique_ptr<int> UniquePtrSource() {
return std::unique_ptr<int>(new int(19)); return std::unique_ptr<int>(new int(19));
} }
std::vector<std::unique_ptr<int>> VectorUniquePtrSource() { std::vector<std::unique_ptr<int>> VectorUniquePtrSource() {
std::vector<std::unique_ptr<int>> out; std::vector<std::unique_ptr<int>> out;
out.emplace_back(new int(7)); out.emplace_back(new int(7));
return out; return out;
} }
skipping to change at line 1405 skipping to change at line 1513
EXPECT_EQ(1, a1.Perform(std::make_tuple(42))); EXPECT_EQ(1, a1.Perform(std::make_tuple(42)));
EXPECT_EQ(0, a2.Perform(std::make_tuple(42))); EXPECT_EQ(0, a2.Perform(std::make_tuple(42)));
// Implicit constructors are allowed. // Implicit constructors are allowed.
const Action<bool(std::string)> s1 = [](std::string s) { return !s.empty(); }; const Action<bool(std::string)> s1 = [](std::string s) { return !s.empty(); };
const Action<int(const char*)> s2 = Action<int(const char*)>(s1); const Action<int(const char*)> s2 = Action<int(const char*)>(s1);
EXPECT_EQ(0, s2.Perform(std::make_tuple(""))); EXPECT_EQ(0, s2.Perform(std::make_tuple("")));
EXPECT_EQ(1, s2.Perform(std::make_tuple("hello"))); EXPECT_EQ(1, s2.Perform(std::make_tuple("hello")));
// Also between the lambda and the action itself. // Also between the lambda and the action itself.
const Action<bool(std::string)> x = [](Unused) { return 42; }; const Action<bool(std::string)> x1 = [](Unused) { return 42; };
EXPECT_TRUE(x.Perform(std::make_tuple("hello"))); const Action<bool(std::string)> x2 = [] { return 42; };
EXPECT_TRUE(x1.Perform(std::make_tuple("hello")));
EXPECT_TRUE(x2.Perform(std::make_tuple("hello")));
// Ensure decay occurs where required.
std::function<int()> f = [] { return 7; };
Action<int(int)> d = f;
f = nullptr;
EXPECT_EQ(7, d.Perform(std::make_tuple(1)));
// Ensure creation of an empty action succeeds.
Action<void(int)>(nullptr);
} }
TEST(FunctorActionTest, UnusedArguments) { TEST(FunctorActionTest, UnusedArguments) {
// Verify that users can ignore uninteresting arguments. // Verify that users can ignore uninteresting arguments.
Action<int(int, double y, double z)> a = Action<int(int, double y, double z)> a =
[](int i, Unused, Unused) { return 2 * i; }; [](int i, Unused, Unused) { return 2 * i; };
std::tuple<int, double, double> dummy = std::make_tuple(3, 7.3, 9.44); std::tuple<int, double, double> dummy = std::make_tuple(3, 7.3, 9.44);
EXPECT_EQ(6, a.Perform(dummy)); EXPECT_EQ(6, a.Perform(dummy));
} }
skipping to change at line 1431 skipping to change at line 1550
a = testing::WithoutArgs([]() { return 7; }); a = testing::WithoutArgs([]() { return 7; });
EXPECT_EQ(7, a.Perform(std::make_tuple(nullptr))); EXPECT_EQ(7, a.Perform(std::make_tuple(nullptr)));
Action<void(std::unique_ptr<int>, int*)> a2 = testing::SetArgPointee<1>(3); Action<void(std::unique_ptr<int>, int*)> a2 = testing::SetArgPointee<1>(3);
int x = 0; int x = 0;
a2.Perform(std::make_tuple(nullptr, &x)); a2.Perform(std::make_tuple(nullptr, &x));
EXPECT_EQ(x, 3); EXPECT_EQ(x, 3);
} }
ACTION(ReturnArity) {
return std::tuple_size<args_type>::value;
}
TEST(ActionMacro, LargeArity) {
EXPECT_EQ(
1, testing::Action<int(int)>(ReturnArity()).Perform(std::make_tuple(0)));
EXPECT_EQ(
10,
testing::Action<int(int, int, int, int, int, int, int, int, int, int)>(
ReturnArity())
.Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)));
EXPECT_EQ(
20,
testing::Action<int(int, int, int, int, int, int, int, int, int, int, int,
int, int, int, int, int, int, int, int, int)>(
ReturnArity())
.Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19)));
}
} // Unnamed namespace } // Unnamed namespace
#ifdef _MSC_VER #ifdef _MSC_VER
#if _MSC_VER == 1900 #if _MSC_VER == 1900
# pragma warning(pop) # pragma warning(pop)
#endif #endif
#endif #endif
 End of changes. 15 change blocks. 
40 lines changed or deleted 180 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)