"Fossies" - the Fresh Open Source Software Archive  

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

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

gmock-actions_test.cc  (googletest-release-1.11.0):gmock-actions_test.cc  (googletest-release-1.12.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 C4100 (unreferenced formal parameter) for MSVC // Silence C4100 (unreferenced formal parameter) and C4503 (decorated name
// length exceeded) for MSVC.
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(push) #pragma warning(push)
# pragma warning(disable:4100) #pragma warning(disable : 4100)
#pragma warning(disable : 4503)
#if _MSC_VER == 1900 #if _MSC_VER == 1900
// and silence C4800 (C4800: 'int *const ': forcing value // and silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15 // 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 <functional>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <vector>
#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-spi.h" #include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
namespace testing {
namespace { namespace {
using ::testing::_;
using ::testing::Action;
using ::testing::ActionInterface;
using ::testing::Assign;
using ::testing::ByMove;
using ::testing::ByRef;
using ::testing::DefaultValue;
using ::testing::DoAll;
using ::testing::DoDefault;
using ::testing::IgnoreResult;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::MakePolymorphicAction;
using ::testing::PolymorphicAction;
using ::testing::Return;
using ::testing::ReturnNew;
using ::testing::ReturnNull;
using ::testing::ReturnRef;
using ::testing::ReturnRefOfCopy;
using ::testing::ReturnRoundRobin;
using ::testing::SetArgPointee;
using ::testing::SetArgumentPointee;
using ::testing::Unused;
using ::testing::WithArgs;
using ::testing::internal::BuiltInDefaultValue; using ::testing::internal::BuiltInDefaultValue;
#if !GTEST_OS_WINDOWS_MOBILE TEST(TypeTraits, Negation) {
using ::testing::SetErrnoAndReturn; // Direct use with std types.
#endif static_assert(std::is_base_of<std::false_type,
internal::negation<std::true_type>>::value,
"");
static_assert(std::is_base_of<std::true_type,
internal::negation<std::false_type>>::value,
"");
// With other types that fit the requirement of a value member that is
// convertible to bool.
static_assert(std::is_base_of<
std::true_type,
internal::negation<std::integral_constant<int, 0>>>::value,
"");
static_assert(std::is_base_of<
std::false_type,
internal::negation<std::integral_constant<int, 1>>>::value,
"");
static_assert(std::is_base_of<
std::false_type,
internal::negation<std::integral_constant<int, -1>>>::value,
"");
}
// Weird false/true types that aren't actually bool constants (but should still
// be legal according to [meta.logical] because `bool(T::value)` is valid), are
// distinct from std::false_type and std::true_type, and are distinct from other
// instantiations of the same template.
//
// These let us check finicky details mandated by the standard like
// "std::conjunction should evaluate to a type that inherits from the first
// false-y input".
template <int>
struct MyFalse : std::integral_constant<int, 0> {};
template <int>
struct MyTrue : std::integral_constant<int, -1> {};
TEST(TypeTraits, Conjunction) {
// Base case: always true.
static_assert(std::is_base_of<std::true_type, internal::conjunction<>>::value,
"");
// One predicate: inherits from that predicate, regardless of value.
static_assert(
std::is_base_of<MyFalse<0>, internal::conjunction<MyFalse<0>>>::value,
"");
static_assert(
std::is_base_of<MyTrue<0>, internal::conjunction<MyTrue<0>>>::value, "");
// Multiple predicates, with at least one false: inherits from that one.
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
MyTrue<2>>>::value,
"");
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
MyFalse<2>>>::value,
"");
// Short circuiting: in the case above, additional predicates need not even
// define a value member.
struct Empty {};
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
Empty>>::value,
"");
// All predicates true: inherits from the last.
static_assert(
std::is_base_of<MyTrue<2>, internal::conjunction<MyTrue<0>, MyTrue<1>,
MyTrue<2>>>::value,
"");
}
TEST(TypeTraits, Disjunction) {
// Base case: always false.
static_assert(
std::is_base_of<std::false_type, internal::disjunction<>>::value, "");
// One predicate: inherits from that predicate, regardless of value.
static_assert(
std::is_base_of<MyFalse<0>, internal::disjunction<MyFalse<0>>>::value,
"");
static_assert(
std::is_base_of<MyTrue<0>, internal::disjunction<MyTrue<0>>>::value, "");
// Multiple predicates, with at least one true: inherits from that one.
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
MyFalse<2>>>::value,
"");
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
MyTrue<2>>>::value,
"");
// Short circuiting: in the case above, additional predicates need not even
// define a value member.
struct Empty {};
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
Empty>>::value,
"");
// All predicates false: inherits from the last.
static_assert(
std::is_base_of<MyFalse<2>, internal::disjunction<MyFalse<0>, MyFalse<1>,
MyFalse<2>>>::value,
"");
}
TEST(TypeTraits, IsInvocableRV) {
struct C {
int operator()() const { return 0; }
void operator()(int) & {}
std::string operator()(int) && { return ""; };
};
// The first overload is callable for const and non-const rvalues and lvalues.
// It can be used to obtain an int, cv void, or anything int is convertible
// to.
static_assert(internal::is_callable_r<int, C>::value, "");
static_assert(internal::is_callable_r<int, C&>::value, "");
static_assert(internal::is_callable_r<int, const C>::value, "");
static_assert(internal::is_callable_r<int, const C&>::value, "");
static_assert(internal::is_callable_r<void, C>::value, "");
static_assert(internal::is_callable_r<const volatile void, C>::value, "");
static_assert(internal::is_callable_r<char, C>::value, "");
// It's possible to provide an int. If it's given to an lvalue, the result is
// void. Otherwise it is std::string (which is also treated as allowed for a
// void result type).
static_assert(internal::is_callable_r<void, C&, int>::value, "");
static_assert(!internal::is_callable_r<int, C&, int>::value, "");
static_assert(!internal::is_callable_r<std::string, C&, int>::value, "");
static_assert(!internal::is_callable_r<void, const C&, int>::value, "");
static_assert(internal::is_callable_r<std::string, C, int>::value, "");
static_assert(internal::is_callable_r<void, C, int>::value, "");
static_assert(!internal::is_callable_r<int, C, int>::value, "");
// It's not possible to provide other arguments.
static_assert(!internal::is_callable_r<void, C, std::string>::value, "");
static_assert(!internal::is_callable_r<void, C, int, int>::value, "");
// In C++17 and above, where it's guaranteed that functions can return
// non-moveable objects, everything should work fine for non-moveable rsult
// types too.
#if defined(__cplusplus) && __cplusplus >= 201703L
{
struct NonMoveable {
NonMoveable() = default;
NonMoveable(NonMoveable&&) = delete;
};
static_assert(!std::is_move_constructible_v<NonMoveable>);
struct Callable {
NonMoveable operator()() { return NonMoveable(); }
};
static_assert(internal::is_callable_r<NonMoveable, Callable>::value);
static_assert(internal::is_callable_r<void, Callable>::value);
static_assert(
internal::is_callable_r<const volatile void, Callable>::value);
static_assert(!internal::is_callable_r<int, Callable>::value);
static_assert(!internal::is_callable_r<NonMoveable, Callable, int>::value);
}
#endif // C++17 and above
// Nothing should choke when we try to call other arguments besides directly
// callable objects, but they should not show up as callable.
static_assert(!internal::is_callable_r<void, int>::value, "");
static_assert(!internal::is_callable_r<void, void (C::*)()>::value, "");
static_assert(!internal::is_callable_r<void, void (C::*)(), C*>::value, "");
}
// 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.
TEST(BuiltInDefaultValueTest, ExistsForPointerTypes) { TEST(BuiltInDefaultValueTest, ExistsForPointerTypes) {
skipping to change at line 116 skipping to change at line 283
EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<char>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<char>::Get());
#if GMOCK_WCHAR_T_IS_NATIVE_ #if GMOCK_WCHAR_T_IS_NATIVE_
#if !defined(__WCHAR_UNSIGNED__) #if !defined(__WCHAR_UNSIGNED__)
EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
#else #else
EXPECT_EQ(0U, BuiltInDefaultValue<wchar_t>::Get()); EXPECT_EQ(0U, BuiltInDefaultValue<wchar_t>::Get());
#endif #endif
#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<unsigned long long>::Get()); // NOLINT EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed long long>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<signed long long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<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());
#if GMOCK_WCHAR_T_IS_NATIVE_ #if GMOCK_WCHAR_T_IS_NATIVE_
EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists());
#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<unsigned long long>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<unsigned long long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<signed long long>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<signed long long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<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.
TEST(BuiltInDefaultValueTest, BoolExists) { TEST(BuiltInDefaultValueTest, BoolExists) {
EXPECT_TRUE(BuiltInDefaultValue<bool>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<bool>::Exists());
} }
// Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a // Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a
// string type. // string type.
TEST(BuiltInDefaultValueTest, IsEmptyStringForString) { TEST(BuiltInDefaultValueTest, IsEmptyStringForString) {
EXPECT_EQ("", BuiltInDefaultValue< ::std::string>::Get()); EXPECT_EQ("", BuiltInDefaultValue<::std::string>::Get());
} }
// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a // Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a
// string type. // string type.
TEST(BuiltInDefaultValueTest, ExistsForString) { TEST(BuiltInDefaultValueTest, ExistsForString) {
EXPECT_TRUE(BuiltInDefaultValue< ::std::string>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<::std::string>::Exists());
} }
// Tests that BuiltInDefaultValue<const T>::Get() returns the same // Tests that BuiltInDefaultValue<const T>::Get() returns the same
// value as BuiltInDefaultValue<T>::Get() does. // value as BuiltInDefaultValue<T>::Get() does.
TEST(BuiltInDefaultValueTest, WorksForConstTypes) { TEST(BuiltInDefaultValueTest, WorksForConstTypes) {
EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get()); EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get());
EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == nullptr); EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == nullptr);
EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get()); EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get());
} }
skipping to change at line 224 skipping to change at line 391
TEST(BuiltInDefaultValueTest, IsDefaultConstructedForDefaultConstructibleType) { TEST(BuiltInDefaultValueTest, IsDefaultConstructedForDefaultConstructibleType) {
EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value()); EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value());
} }
TEST(BuiltInDefaultValueTest, DoesNotExistForNonDefaultConstructibleType) { TEST(BuiltInDefaultValueTest, DoesNotExistForNonDefaultConstructibleType) {
EXPECT_FALSE(BuiltInDefaultValue<MyNonDefaultConstructible>::Exists()); EXPECT_FALSE(BuiltInDefaultValue<MyNonDefaultConstructible>::Exists());
} }
// Tests that BuiltInDefaultValue<T&>::Get() aborts the program. // Tests that BuiltInDefaultValue<T&>::Get() aborts the program.
TEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) { TEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) {
EXPECT_DEATH_IF_SUPPORTED({ EXPECT_DEATH_IF_SUPPORTED({ BuiltInDefaultValue<int&>::Get(); }, "");
BuiltInDefaultValue<int&>::Get(); EXPECT_DEATH_IF_SUPPORTED({ BuiltInDefaultValue<const char&>::Get(); }, "");
}, "");
EXPECT_DEATH_IF_SUPPORTED({
BuiltInDefaultValue<const char&>::Get();
}, "");
} }
TEST(BuiltInDefaultValueDeathTest, IsUndefinedForNonDefaultConstructibleType) { TEST(BuiltInDefaultValueDeathTest, IsUndefinedForNonDefaultConstructibleType) {
EXPECT_DEATH_IF_SUPPORTED({ EXPECT_DEATH_IF_SUPPORTED(
BuiltInDefaultValue<MyNonDefaultConstructible>::Get(); { BuiltInDefaultValue<MyNonDefaultConstructible>::Get(); }, "");
}, "");
} }
// Tests that DefaultValue<T>::IsSet() is false initially. // Tests that DefaultValue<T>::IsSet() is false initially.
TEST(DefaultValueTest, IsInitiallyUnset) { TEST(DefaultValueTest, IsInitiallyUnset) {
EXPECT_FALSE(DefaultValue<int>::IsSet()); EXPECT_FALSE(DefaultValue<int>::IsSet());
EXPECT_FALSE(DefaultValue<MyDefaultConstructible>::IsSet()); EXPECT_FALSE(DefaultValue<MyDefaultConstructible>::IsSet());
EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::IsSet()); EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::IsSet());
} }
// Tests that DefaultValue<T> can be set and then unset. // Tests that DefaultValue<T> can be set and then unset.
skipping to change at line 281 skipping to change at line 443
// BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is // BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is
// false. // false.
TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) { TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
EXPECT_FALSE(DefaultValue<int>::IsSet()); EXPECT_FALSE(DefaultValue<int>::IsSet());
EXPECT_TRUE(DefaultValue<int>::Exists()); EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::IsSet()); EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::IsSet());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::Exists()); EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::Exists());
EXPECT_EQ(0, DefaultValue<int>::Get()); EXPECT_EQ(0, DefaultValue<int>::Get());
EXPECT_DEATH_IF_SUPPORTED({ EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); },
DefaultValue<MyNonDefaultConstructible>::Get(); "");
}, "");
} }
TEST(DefaultValueTest, GetWorksForMoveOnlyIfSet) { TEST(DefaultValueTest, GetWorksForMoveOnlyIfSet) {
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists()); EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists());
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == nullptr); EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == nullptr);
DefaultValue<std::unique_ptr<int>>::SetFactory([] { DefaultValue<std::unique_ptr<int>>::SetFactory(
return std::unique_ptr<int>(new int(42)); [] { return std::unique_ptr<int>(new int(42)); });
});
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists()); EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists());
std::unique_ptr<int> i = DefaultValue<std::unique_ptr<int>>::Get(); std::unique_ptr<int> i = DefaultValue<std::unique_ptr<int>>::Get();
EXPECT_EQ(42, *i); EXPECT_EQ(42, *i);
} }
// Tests that DefaultValue<void>::Get() returns void. // Tests that DefaultValue<void>::Get() returns void.
TEST(DefaultValueTest, GetWorksForVoid) { TEST(DefaultValueTest, GetWorksForVoid) { return DefaultValue<void>::Get(); }
return DefaultValue<void>::Get();
}
// Tests using DefaultValue with a reference type. // Tests using DefaultValue with a reference type.
// Tests that DefaultValue<T&>::IsSet() is false initially. // Tests that DefaultValue<T&>::IsSet() is false initially.
TEST(DefaultValueOfReferenceTest, IsInitiallyUnset) { TEST(DefaultValueOfReferenceTest, IsInitiallyUnset) {
EXPECT_FALSE(DefaultValue<int&>::IsSet()); EXPECT_FALSE(DefaultValue<int&>::IsSet());
EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::IsSet()); EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::IsSet());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet()); EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
} }
skipping to change at line 348 skipping to change at line 506
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet()); EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
} }
// Tests that DefaultValue<T&>::Get() returns the // Tests that DefaultValue<T&>::Get() returns the
// BuiltInDefaultValue<T&>::Get() when DefaultValue<T&>::IsSet() is // BuiltInDefaultValue<T&>::Get() when DefaultValue<T&>::IsSet() is
// false. // false.
TEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) { TEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
EXPECT_FALSE(DefaultValue<int&>::IsSet()); EXPECT_FALSE(DefaultValue<int&>::IsSet());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet()); EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
EXPECT_DEATH_IF_SUPPORTED({ EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<int&>::Get(); }, "");
DefaultValue<int&>::Get(); EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); },
}, ""); "");
EXPECT_DEATH_IF_SUPPORTED({
DefaultValue<MyNonDefaultConstructible>::Get();
}, "");
} }
// Tests that ActionInterface can be implemented by defining the // Tests that ActionInterface can be implemented by defining the
// Perform method. // Perform method.
typedef int MyGlobalFunction(bool, int); typedef int MyGlobalFunction(bool, int);
class MyActionImpl : public ActionInterface<MyGlobalFunction> { class MyActionImpl : public ActionInterface<MyGlobalFunction> {
public: public:
int Perform(const std::tuple<bool, int>& args) override { int Perform(const std::tuple<bool, int>& args) override {
skipping to change at line 384 skipping to change at line 539
Action<MyGlobalFunction> action = MakeAction(new MyActionImpl); Action<MyGlobalFunction> action = MakeAction(new MyActionImpl);
// When exercising the Perform() method of Action<F>, we must pass // When exercising the Perform() method of Action<F>, we must pass
// it a tuple whose size and type are compatible with F's argument // it a tuple whose size and type are compatible with F's argument
// types. For example, if F is int(), then Perform() takes a // types. For example, if F is int(), then Perform() takes a
// 0-tuple; if F is void(bool, int), then Perform() takes a // 0-tuple; if F is void(bool, int), then Perform() takes a
// std::tuple<bool, int>, and so on. // std::tuple<bool, int>, and so on.
EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5))); EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5)));
} }
// Tests that Action<F> can be contructed from a pointer to // Tests that Action<F> can be constructed from a pointer to
// ActionInterface<F>. // ActionInterface<F>.
TEST(ActionTest, CanBeConstructedFromActionInterface) { TEST(ActionTest, CanBeConstructedFromActionInterface) {
Action<MyGlobalFunction> action(new MyActionImpl); Action<MyGlobalFunction> action(new MyActionImpl);
} }
// Tests that Action<F> delegates actual work to ActionInterface<F>. // Tests that Action<F> delegates actual work to ActionInterface<F>.
TEST(ActionTest, DelegatesWorkToActionInterface) { TEST(ActionTest, DelegatesWorkToActionInterface) {
const Action<MyGlobalFunction> action(new MyActionImpl); const Action<MyGlobalFunction> action(new MyActionImpl);
EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5))); EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5)));
skipping to change at line 433 skipping to change at line 588
// compatible Action<To> object. // compatible Action<To> object.
class IsNotZero : public ActionInterface<bool(int)> { // NOLINT class IsNotZero : public ActionInterface<bool(int)> { // NOLINT
public: public:
bool Perform(const std::tuple<int>& arg) override { bool Perform(const std::tuple<int>& arg) override {
return std::get<0>(arg) != 0; return std::get<0>(arg) != 0;
} }
}; };
TEST(ActionTest, CanBeConvertedToOtherActionType) { TEST(ActionTest, CanBeConvertedToOtherActionType) {
const Action<bool(int)> a1(new IsNotZero); // NOLINT const Action<bool(int)> a1(new IsNotZero); // NOLINT
const Action<int(char)> a2 = Action<int(char)>(a1); // NOLINT const Action<int(char)> a2 = Action<int(char)>(a1); // NOLINT
EXPECT_EQ(1, a2.Perform(std::make_tuple('a'))); EXPECT_EQ(1, a2.Perform(std::make_tuple('a')));
EXPECT_EQ(0, a2.Perform(std::make_tuple('\0'))); EXPECT_EQ(0, a2.Perform(std::make_tuple('\0')));
} }
// The following two classes are for testing MakePolymorphicAction(). // The following two classes are for testing MakePolymorphicAction().
// Implements a polymorphic action that returns the second of the // Implements a polymorphic action that returns the second of the
// arguments it receives. // arguments it receives.
class ReturnSecondArgumentAction { class ReturnSecondArgumentAction {
skipping to change at line 525 skipping to change at line 680
// Tests that Return("string literal") works. // Tests that Return("string literal") works.
TEST(ReturnTest, AcceptsStringLiteral) { TEST(ReturnTest, AcceptsStringLiteral) {
Action<const char*()> a1 = Return("Hello"); Action<const char*()> a1 = Return("Hello");
EXPECT_STREQ("Hello", a1.Perform(std::make_tuple())); EXPECT_STREQ("Hello", a1.Perform(std::make_tuple()));
Action<std::string()> a2 = Return("world"); Action<std::string()> a2 = Return("world");
EXPECT_EQ("world", a2.Perform(std::make_tuple())); EXPECT_EQ("world", a2.Perform(std::make_tuple()));
} }
// Test struct which wraps a vector of integers. Used in // Return(x) should work fine when the mock function's return type is a
// 'SupportsWrapperReturnType' test. // reference-like wrapper for decltype(x), as when x is a std::string and the
struct IntegerVectorWrapper { // mock function returns std::string_view.
std::vector<int> * v; TEST(ReturnTest, SupportsReferenceLikeReturnType) {
IntegerVectorWrapper(std::vector<int>& _v) : v(&_v) {} // NOLINT // A reference wrapper for std::vector<int>, implicitly convertible from it.
}; struct Result {
const std::vector<int>* v;
// Tests that Return() works when return type is a wrapper type. Result(const std::vector<int>& v) : v(&v) {} // NOLINT
TEST(ReturnTest, SupportsWrapperReturnType) { };
// Initialize vector of integers.
std::vector<int> v; // Set up an action for a mock function that returns the reference wrapper
for (int i = 0; i < 5; ++i) v.push_back(i); // type, initializing it with an actual vector.
//
// Return() called with 'v' as argument. The Action will return the same data // The returned wrapper should be initialized with a copy of that vector
// as 'v' (copy) but it will be wrapped in an IntegerVectorWrapper. // that's embedded within the action itself (which should stay alive as long
Action<IntegerVectorWrapper()> a = Return(v); // as the mock object is alive), rather than e.g. a reference to the temporary
const std::vector<int>& result = *(a.Perform(std::make_tuple()).v); // we feed to Return. This should work fine both for WillOnce and
EXPECT_THAT(result, ::testing::ElementsAre(0, 1, 2, 3, 4)); // WillRepeatedly.
MockFunction<Result()> mock;
EXPECT_CALL(mock, Call)
.WillOnce(Return(std::vector<int>{17, 19, 23}))
.WillRepeatedly(Return(std::vector<int>{29, 31, 37}));
EXPECT_THAT(mock.AsStdFunction()(),
Field(&Result::v, Pointee(ElementsAre(17, 19, 23))));
EXPECT_THAT(mock.AsStdFunction()(),
Field(&Result::v, Pointee(ElementsAre(29, 31, 37))));
}
TEST(ReturnTest, PrefersConversionOperator) {
// Define types In and Out such that:
//
// * In is implicitly convertible to Out.
// * Out also has an explicit constructor from In.
//
struct In;
struct Out {
int x;
explicit Out(const int x) : x(x) {}
explicit Out(const In&) : x(0) {}
};
struct In {
operator Out() const { return Out{19}; } // NOLINT
};
// Assumption check: the C++ language rules are such that a function that
// returns Out which uses In a return statement will use the implicit
// conversion path rather than the explicit constructor.
EXPECT_THAT([]() -> Out { return In(); }(), Field(&Out::x, 19));
// Return should work the same way: if the mock function's return type is Out
// and we feed Return an In value, then the Out should be created through the
// implicit conversion path rather than the explicit constructor.
MockFunction<Out()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return(In()));
EXPECT_THAT(mock.AsStdFunction()(), Field(&Out::x, 19));
}
// It should be possible to use Return(R) with a mock function result type U
// that is convertible from const R& but *not* R (such as
// std::reference_wrapper). This should work for both WillOnce and
// WillRepeatedly.
TEST(ReturnTest, ConversionRequiresConstLvalueReference) {
using R = int;
using U = std::reference_wrapper<const int>;
static_assert(std::is_convertible<const R&, U>::value, "");
static_assert(!std::is_convertible<R, U>::value, "");
MockFunction<U()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return(17)).WillRepeatedly(Return(19));
EXPECT_EQ(17, mock.AsStdFunction()());
EXPECT_EQ(19, mock.AsStdFunction()());
}
// Return(x) should not be usable with a mock function result type that's
// implicitly convertible from decltype(x) but requires a non-const lvalue
// reference to the input. It doesn't make sense for the conversion operator to
// modify the input.
TEST(ReturnTest, ConversionRequiresMutableLvalueReference) {
// Set up a type that is implicitly convertible from std::string&, but not
// std::string&& or `const std::string&`.
//
// Avoid asserting about conversion from std::string on MSVC, which seems to
// implement std::is_convertible incorrectly in this case.
struct S {
S(std::string&) {} // NOLINT
};
static_assert(std::is_convertible<std::string&, S>::value, "");
#ifndef _MSC_VER
static_assert(!std::is_convertible<std::string&&, S>::value, "");
#endif
static_assert(!std::is_convertible<const std::string&, S>::value, "");
// It shouldn't be possible to use the result of Return(std::string) in a
// context where an S is needed.
//
// Here too we disable the assertion for MSVC, since its incorrect
// implementation of is_convertible causes our SFINAE to be wrong.
using RA = decltype(Return(std::string()));
static_assert(!std::is_convertible<RA, Action<S()>>::value, "");
#ifndef _MSC_VER
static_assert(!std::is_convertible<RA, OnceAction<S()>>::value, "");
#endif
}
TEST(ReturnTest, MoveOnlyResultType) {
// Return should support move-only result types when used with WillOnce.
{
MockFunction<std::unique_ptr<int>()> mock;
EXPECT_CALL(mock, Call)
// NOLINTNEXTLINE
.WillOnce(Return(std::unique_ptr<int>(new int(17))));
EXPECT_THAT(mock.AsStdFunction()(), Pointee(17));
}
// The result of Return should not be convertible to Action (so it can't be
// used with WillRepeatedly).
static_assert(!std::is_convertible<decltype(Return(std::unique_ptr<int>())),
Action<std::unique_ptr<int>()>>::value,
"");
} }
// Tests that Return(v) is covaraint. // Tests that Return(v) is covaraint.
struct Base { struct Base {
bool operator==(const Base&) { return true; } bool operator==(const Base&) { return true; }
}; };
struct Derived : public Base { struct Derived : public Base {
bool operator==(const Derived&) { return true; } bool operator==(const Derived&) { return true; }
skipping to change at line 596 skipping to change at line 861
FromType x(&converted); FromType x(&converted);
Action<ToType()> action(Return(x)); Action<ToType()> action(Return(x));
EXPECT_TRUE(converted) << "Return must convert its argument in its own " EXPECT_TRUE(converted) << "Return must convert its argument in its own "
<< "conversion operator."; << "conversion operator.";
converted = false; converted = false;
action.Perform(std::tuple<>()); action.Perform(std::tuple<>());
EXPECT_FALSE(converted) << "Action must NOT convert its argument " EXPECT_FALSE(converted) << "Action must NOT convert its argument "
<< "when performed."; << "when performed.";
} }
class DestinationType {};
class SourceType {
public:
// Note: a non-const typecast operator.
operator DestinationType() { return DestinationType(); }
};
TEST(ReturnTest, CanConvertArgumentUsingNonConstTypeCastOperator) {
SourceType s;
Action<DestinationType()> action(Return(s));
}
// Tests that ReturnNull() returns NULL in a pointer-returning function. // Tests that ReturnNull() returns NULL in a pointer-returning function.
TEST(ReturnNullTest, WorksInPointerReturningFunction) { TEST(ReturnNullTest, WorksInPointerReturningFunction) {
const Action<int*()> a1 = ReturnNull(); const Action<int*()> a1 = ReturnNull();
EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr); EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr);
const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT
EXPECT_TRUE(a2.Perform(std::make_tuple(true)) == nullptr); EXPECT_TRUE(a2.Perform(std::make_tuple(true)) == nullptr);
} }
// Tests that ReturnNull() returns NULL for shared_ptr and unique_ptr returning // Tests that ReturnNull() returns NULL for shared_ptr and unique_ptr returning
skipping to change at line 648 skipping to change at line 900
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&&>()))> template <typename T, typename = decltype(ReturnRef(std::declval<T&&>()))>
bool CanCallReturnRef(T&&) { return true; } bool CanCallReturnRef(T&&) {
return true;
}
bool CanCallReturnRef(Unused) { return false; } bool CanCallReturnRef(Unused) { return false; }
// Tests that ReturnRef(v) is working with non-temporaries (T&) // Tests that ReturnRef(v) is working with non-temporaries (T&)
TEST(ReturnRefTest, WorksForNonTemporary) { TEST(ReturnRefTest, WorksForNonTemporary) {
int scalar_value = 123; int scalar_value = 123;
EXPECT_TRUE(CanCallReturnRef(scalar_value)); EXPECT_TRUE(CanCallReturnRef(scalar_value));
std::string non_scalar_value("ABC"); std::string non_scalar_value("ABC");
EXPECT_TRUE(CanCallReturnRef(non_scalar_value)); EXPECT_TRUE(CanCallReturnRef(non_scalar_value));
const int const_scalar_value{321}; const int const_scalar_value{321};
EXPECT_TRUE(CanCallReturnRef(const_scalar_value)); EXPECT_TRUE(CanCallReturnRef(const_scalar_value));
const std::string const_non_scalar_value("CBA"); const std::string const_non_scalar_value("CBA");
EXPECT_TRUE(CanCallReturnRef(const_non_scalar_value)); EXPECT_TRUE(CanCallReturnRef(const_non_scalar_value));
} }
// Tests that ReturnRef(v) is not working with temporaries (T&&) // Tests that ReturnRef(v) is not working with temporaries (T&&)
TEST(ReturnRefTest, DoesNotWorkForTemporary) { TEST(ReturnRefTest, DoesNotWorkForTemporary) {
auto scalar_value = []() -> int { return 123; }; auto scalar_value = []() -> int { return 123; };
EXPECT_FALSE(CanCallReturnRef(scalar_value())); EXPECT_FALSE(CanCallReturnRef(scalar_value()));
auto non_scalar_value = []() -> std::string { return "ABC"; }; auto non_scalar_value = []() -> std::string { return "ABC"; };
EXPECT_FALSE(CanCallReturnRef(non_scalar_value())); EXPECT_FALSE(CanCallReturnRef(non_scalar_value()));
// cannot use here callable returning "const scalar type", // cannot use here callable returning "const scalar type",
// because such const for scalar return type is ignored // because such const for scalar return type is ignored
EXPECT_FALSE(CanCallReturnRef(static_cast<const int>(321))); EXPECT_FALSE(CanCallReturnRef(static_cast<const int>(321)));
auto const_non_scalar_value = []() -> const std::string { return "CBA"; }; auto const_non_scalar_value = []() -> const std::string { return "CBA"; };
skipping to change at line 747 skipping to change at line 1001
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>());
MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>()); MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>());
MOCK_METHOD1(TakeUnique, int(std::unique_ptr<int>)); MOCK_METHOD1(TakeUnique, int(std::unique_ptr<int>));
MOCK_METHOD2(TakeUnique, MOCK_METHOD2(TakeUnique,
int(const std::unique_ptr<int>&, std::unique_ptr<int>)); int(const std::unique_ptr<int>&, std::unique_ptr<int>));
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockClass); MockClass(const MockClass&) = delete;
MockClass& operator=(const MockClass&) = delete;
}; };
// Tests that DoDefault() returns the built-in default value for the // Tests that DoDefault() returns the built-in default value for the
// return type by default. // return type by default.
TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) { TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) {
MockClass mock; MockClass mock;
EXPECT_CALL(mock, IntFunc(_)) EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault());
.WillOnce(DoDefault());
EXPECT_EQ(0, mock.IntFunc(true)); EXPECT_EQ(0, mock.IntFunc(true));
} }
// Tests that DoDefault() throws (when exceptions are enabled) or aborts // Tests that DoDefault() throws (when exceptions are enabled) or aborts
// the process when there is no built-in default value for the return type. // the process when there is no built-in default value for the return type.
TEST(DoDefaultDeathTest, DiesForUnknowType) { TEST(DoDefaultDeathTest, DiesForUnknowType) {
MockClass mock; MockClass mock;
EXPECT_CALL(mock, Foo()) EXPECT_CALL(mock, Foo()).WillRepeatedly(DoDefault());
.WillRepeatedly(DoDefault());
#if GTEST_HAS_EXCEPTIONS #if GTEST_HAS_EXCEPTIONS
EXPECT_ANY_THROW(mock.Foo()); EXPECT_ANY_THROW(mock.Foo());
#else #else
EXPECT_DEATH_IF_SUPPORTED({ EXPECT_DEATH_IF_SUPPORTED({ mock.Foo(); }, "");
mock.Foo();
}, "");
#endif #endif
} }
// Tests that using DoDefault() inside a composite action leads to a // Tests that using DoDefault() inside a composite action leads to a
// run-time error. // run-time error.
void VoidFunc(bool /* flag */) {} void VoidFunc(bool /* flag */) {}
TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) { TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
MockClass mock; MockClass mock;
EXPECT_CALL(mock, IntFunc(_)) EXPECT_CALL(mock, IntFunc(_))
.WillRepeatedly(DoAll(Invoke(VoidFunc), .WillRepeatedly(DoAll(Invoke(VoidFunc), DoDefault()));
DoDefault()));
// 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 overridden 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().
TEST(DoDefaultTest, DoesWhatOnCallSpecifies) { TEST(DoDefaultTest, DoesWhatOnCallSpecifies) {
MockClass mock; MockClass mock;
ON_CALL(mock, IntFunc(_)) ON_CALL(mock, IntFunc(_)).WillByDefault(Return(2));
.WillByDefault(Return(2)); EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault());
EXPECT_CALL(mock, IntFunc(_))
.WillOnce(DoDefault());
EXPECT_EQ(2, mock.IntFunc(false)); EXPECT_EQ(2, mock.IntFunc(false));
} }
// Tests that using DoDefault() in ON_CALL() leads to a run-time failure. // Tests that using DoDefault() in ON_CALL() leads to a run-time failure.
TEST(DoDefaultTest, CannotBeUsedInOnCall) { TEST(DoDefaultTest, CannotBeUsedInOnCall) {
MockClass mock; MockClass mock;
EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_NONFATAL_FAILURE(
ON_CALL(mock, IntFunc(_)) { // NOLINT
.WillByDefault(DoDefault()); ON_CALL(mock, IntFunc(_)).WillByDefault(DoDefault());
}, "DoDefault() cannot be used in ON_CALL()"); },
"DoDefault() cannot be used in ON_CALL()");
} }
// Tests that SetArgPointee<N>(v) sets the variable pointed to by // Tests that SetArgPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v. // the N-th (0-based) argument to v.
TEST(SetArgPointeeTest, SetsTheNthPointee) { TEST(SetArgPointeeTest, SetsTheNthPointee) {
typedef void MyFunction(bool, int*, char*); typedef void MyFunction(bool, int*, char*);
Action<MyFunction> a = SetArgPointee<1>(2); Action<MyFunction> a = SetArgPointee<1>(2);
int n = 0; int n = 0;
char ch = '\0'; char ch = '\0';
skipping to change at line 868 skipping to change at line 1114
EXPECT_STREQ("world", ptr); EXPECT_STREQ("world", ptr);
} }
TEST(SetArgPointeeTest, AcceptsWideStringLiteral) { TEST(SetArgPointeeTest, AcceptsWideStringLiteral) {
typedef void MyFunction(const wchar_t**); typedef void MyFunction(const wchar_t**);
Action<MyFunction> a = SetArgPointee<0>(L"world"); Action<MyFunction> a = SetArgPointee<0>(L"world");
const wchar_t* ptr = nullptr; const wchar_t* ptr = nullptr;
a.Perform(std::make_tuple(&ptr)); a.Perform(std::make_tuple(&ptr));
EXPECT_STREQ(L"world", ptr); EXPECT_STREQ(L"world", ptr);
# if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
typedef void MyStringFunction(std::wstring*); typedef void MyStringFunction(std::wstring*);
Action<MyStringFunction> a2 = SetArgPointee<0>(L"world"); Action<MyStringFunction> a2 = SetArgPointee<0>(L"world");
std::wstring str = L""; std::wstring str = L"";
a2.Perform(std::make_tuple(&str)); a2.Perform(std::make_tuple(&str));
EXPECT_EQ(L"world", str); EXPECT_EQ(L"world", str);
# endif #endif
} }
// Tests that SetArgPointee<N>() accepts a char pointer. // Tests that SetArgPointee<N>() accepts a char pointer.
TEST(SetArgPointeeTest, AcceptsCharPointer) { TEST(SetArgPointeeTest, AcceptsCharPointer) {
typedef void MyFunction(bool, std::string*, const char**); typedef void MyFunction(bool, std::string*, const char**);
const char* const hi = "hi"; const char* const hi = "hi";
Action<MyFunction> a = SetArgPointee<1>(hi); Action<MyFunction> a = SetArgPointee<1>(hi);
std::string str; std::string str;
const char* ptr = nullptr; const char* ptr = nullptr;
a.Perform(std::make_tuple(true, &str, &ptr)); a.Perform(std::make_tuple(true, &str, &ptr));
skipping to change at line 907 skipping to change at line 1153
} }
TEST(SetArgPointeeTest, AcceptsWideCharPointer) { TEST(SetArgPointeeTest, AcceptsWideCharPointer) {
typedef void MyFunction(bool, const wchar_t**); typedef void MyFunction(bool, const wchar_t**);
const wchar_t* const hi = L"hi"; const wchar_t* const hi = L"hi";
Action<MyFunction> a = SetArgPointee<1>(hi); Action<MyFunction> a = SetArgPointee<1>(hi);
const wchar_t* ptr = nullptr; const wchar_t* ptr = nullptr;
a.Perform(std::make_tuple(true, &ptr)); a.Perform(std::make_tuple(true, &ptr));
EXPECT_EQ(hi, ptr); EXPECT_EQ(hi, ptr);
# if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
typedef void MyStringFunction(bool, std::wstring*); typedef void MyStringFunction(bool, std::wstring*);
wchar_t world_array[] = L"world"; wchar_t world_array[] = L"world";
wchar_t* const world = world_array; wchar_t* const world = world_array;
Action<MyStringFunction> a2 = SetArgPointee<1>(world); Action<MyStringFunction> a2 = SetArgPointee<1>(world);
std::wstring str; std::wstring str;
a2.Perform(std::make_tuple(true, &str)); a2.Perform(std::make_tuple(true, &str));
EXPECT_EQ(world_array, str); EXPECT_EQ(world_array, str);
# endif #endif
} }
// Tests that SetArgumentPointee<N>(v) sets the variable pointed to by // Tests that SetArgumentPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v. // the N-th (0-based) argument to v.
TEST(SetArgumentPointeeTest, SetsTheNthPointee) { TEST(SetArgumentPointeeTest, SetsTheNthPointee) {
typedef void MyFunction(bool, int*, char*); typedef void MyFunction(bool, int*, char*);
Action<MyFunction> a = SetArgumentPointee<1>(2); Action<MyFunction> a = SetArgumentPointee<1>(2);
int n = 0; int n = 0;
char ch = '\0'; char ch = '\0';
skipping to change at line 1079 skipping to change at line 1325
EXPECT_EQ("Hello, world", x); EXPECT_EQ("Hello, world", x);
} }
TEST(AssignTest, CompatibleTypes) { TEST(AssignTest, CompatibleTypes) {
double x = 0; double x = 0;
Action<void(int)> a = Assign(&x, 5); Action<void(int)> a = Assign(&x, 5);
a.Perform(std::make_tuple(0)); a.Perform(std::make_tuple(0));
EXPECT_DOUBLE_EQ(5, x); EXPECT_DOUBLE_EQ(5, x);
} }
// DoAll should support &&-qualified actions when used with WillOnce.
TEST(DoAll, SupportsRefQualifiedActions) {
struct InitialAction {
void operator()(const int arg) && { EXPECT_EQ(17, arg); }
};
struct FinalAction {
int operator()() && { return 19; }
};
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call).WillOnce(DoAll(InitialAction{}, FinalAction{}));
EXPECT_EQ(19, mock.AsStdFunction()(17));
}
// DoAll should never provide rvalue references to the initial actions. If the
// mock action itself accepts an rvalue reference or a non-scalar object by
// value then the final action should receive an rvalue reference, but initial
// actions should receive only lvalue references.
TEST(DoAll, ProvidesLvalueReferencesToInitialActions) {
struct Obj {};
// Mock action accepts by value: the initial action should be fed a const
// lvalue reference, and the final action an rvalue reference.
{
struct InitialAction {
void operator()(Obj&) const { FAIL() << "Unexpected call"; }
void operator()(const Obj&) const {}
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
void operator()(const Obj&&) const { FAIL() << "Unexpected call"; }
};
MockFunction<void(Obj)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}))
.WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}));
mock.AsStdFunction()(Obj{});
mock.AsStdFunction()(Obj{});
}
// Mock action accepts by const lvalue reference: both actions should receive
// a const lvalue reference.
{
struct InitialAction {
void operator()(Obj&) const { FAIL() << "Unexpected call"; }
void operator()(const Obj&) const {}
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
void operator()(const Obj&&) const { FAIL() << "Unexpected call"; }
};
MockFunction<void(const Obj&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](const Obj&) {}))
.WillRepeatedly(
DoAll(InitialAction{}, InitialAction{}, [](const Obj&) {}));
mock.AsStdFunction()(Obj{});
mock.AsStdFunction()(Obj{});
}
// Mock action accepts by non-const lvalue reference: both actions should get
// a non-const lvalue reference if they want them.
{
struct InitialAction {
void operator()(Obj&) const {}
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
};
MockFunction<void(Obj&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {}))
.WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {}));
Obj obj;
mock.AsStdFunction()(obj);
mock.AsStdFunction()(obj);
}
// Mock action accepts by rvalue reference: the initial actions should receive
// a non-const lvalue reference if it wants it, and the final action an rvalue
// reference.
{
struct InitialAction {
void operator()(Obj&) const {}
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
};
MockFunction<void(Obj &&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}))
.WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}));
mock.AsStdFunction()(Obj{});
mock.AsStdFunction()(Obj{});
}
// &&-qualified initial actions should also be allowed with WillOnce.
{
struct InitialAction {
void operator()(Obj&) && {}
};
MockFunction<void(Obj&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {}));
Obj obj;
mock.AsStdFunction()(obj);
}
{
struct InitialAction {
void operator()(Obj&) && {}
};
MockFunction<void(Obj &&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}));
mock.AsStdFunction()(Obj{});
}
}
// DoAll should support being used with type-erased Action objects, both through
// WillOnce and WillRepeatedly.
TEST(DoAll, SupportsTypeErasedActions) {
// With only type-erased actions.
const Action<void()> initial_action = [] {};
const Action<int()> final_action = [] { return 17; };
MockFunction<int()> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(initial_action, initial_action, final_action))
.WillRepeatedly(DoAll(initial_action, initial_action, final_action));
EXPECT_EQ(17, mock.AsStdFunction()());
// With &&-qualified and move-only final action.
{
struct FinalAction {
FinalAction() = default;
FinalAction(FinalAction&&) = default;
int operator()() && { return 17; }
};
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(initial_action, initial_action, FinalAction{}));
EXPECT_EQ(17, mock.AsStdFunction()());
}
}
// Tests using WithArgs and with an action that takes 1 argument. // Tests using WithArgs and with an action that takes 1 argument.
TEST(WithArgsTest, OneArg) { TEST(WithArgsTest, OneArg) {
Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT
EXPECT_TRUE(a.Perform(std::make_tuple(1.5, -1))); EXPECT_TRUE(a.Perform(std::make_tuple(1.5, -1)));
EXPECT_FALSE(a.Perform(std::make_tuple(1.5, 1))); EXPECT_FALSE(a.Perform(std::make_tuple(1.5, 1)));
} }
// Tests using WithArgs with an action that takes 2 arguments. // Tests using WithArgs with an action that takes 2 arguments.
TEST(WithArgsTest, TwoArgs) { TEST(WithArgsTest, TwoArgs) {
Action<const char*(const char* s, double x, short n)> a = // NOLINT Action<const char*(const char* s, double x, short n)> a = // NOLINT
skipping to change at line 1174 skipping to change at line 1574
TEST(WithArgsTest, ReturnReference) { TEST(WithArgsTest, ReturnReference) {
Action<int&(int&, void*)> aa = WithArgs<0>([](int& a) -> int& { return a; }); Action<int&(int&, void*)> aa = WithArgs<0>([](int& a) -> int& { return a; });
int i = 0; int i = 0;
const int& res = aa.Perform(std::forward_as_tuple(i, nullptr)); const int& res = aa.Perform(std::forward_as_tuple(i, nullptr));
EXPECT_EQ(&i, &res); EXPECT_EQ(&i, &res);
} }
TEST(WithArgsTest, InnerActionWithConversion) { TEST(WithArgsTest, InnerActionWithConversion) {
Action<Derived*()> inner = [] { return nullptr; }; Action<Derived*()> inner = [] { return nullptr; };
Action<Base*(double)> a = testing::WithoutArgs(inner);
EXPECT_EQ(nullptr, a.Perform(std::make_tuple(1.1))); MockFunction<Base*(double)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(WithoutArgs(inner))
.WillRepeatedly(WithoutArgs(inner));
EXPECT_EQ(nullptr, mock.AsStdFunction()(1.1));
EXPECT_EQ(nullptr, mock.AsStdFunction()(1.1));
}
// It should be possible to use an &&-qualified inner action as long as the
// whole shebang is used as an rvalue with WillOnce.
TEST(WithArgsTest, RefQualifiedInnerAction) {
struct SomeAction {
int operator()(const int arg) && {
EXPECT_EQ(17, arg);
return 19;
}
};
MockFunction<int(int, int)> mock;
EXPECT_CALL(mock, Call).WillOnce(WithArg<1>(SomeAction{}));
EXPECT_EQ(19, mock.AsStdFunction()(0, 17));
} }
#if !GTEST_OS_WINDOWS_MOBILE #if !GTEST_OS_WINDOWS_MOBILE
class SetErrnoAndReturnTest : public testing::Test { class SetErrnoAndReturnTest : public testing::Test {
protected: protected:
void SetUp() override { errno = 0; } void SetUp() override { errno = 0; }
void TearDown() override { errno = 0; } void TearDown() override { errno = 0; }
}; };
skipping to change at line 1234 skipping to change at line 1655
// Copies ref_wrapper1 to ref_wrapper. // Copies ref_wrapper1 to ref_wrapper.
ref_wrapper = ref_wrapper1; ref_wrapper = ref_wrapper1;
const std::string& r3 = ref_wrapper; const std::string& r3 = ref_wrapper;
EXPECT_EQ(&s1, &r3); EXPECT_EQ(&s1, &r3);
} }
// Tests using ByRef() on a const value. // Tests using ByRef() on a const value.
TEST(ByRefTest, ConstValue) { TEST(ByRefTest, ConstValue) {
const int n = 0; const int n = 0;
// int& ref = ByRef(n); // This shouldn't compile - we have a // int& ref = ByRef(n); // This shouldn't compile - we have a
// negative compilation test to catch it. // negative compilation test to catch it.
const int& const_ref = ByRef(n); const int& const_ref = ByRef(n);
EXPECT_EQ(&n, &const_ref); EXPECT_EQ(&n, &const_ref);
} }
// Tests using ByRef() on a non-const value. // Tests using ByRef() on a non-const value.
TEST(ByRefTest, NonConstValue) { TEST(ByRefTest, NonConstValue) {
int n = 0; int n = 0;
// ByRef(n) can be used as either an int&, // ByRef(n) can be used as either an int&,
int& ref = ByRef(n); int& ref = ByRef(n);
skipping to change at line 1259 skipping to change at line 1680
EXPECT_EQ(&n, &const_ref); EXPECT_EQ(&n, &const_ref);
} }
// Tests explicitly specifying the type when using ByRef(). // Tests explicitly specifying the type when using ByRef().
TEST(ByRefTest, ExplicitType) { TEST(ByRefTest, ExplicitType) {
int n = 0; int n = 0;
const int& r1 = ByRef<const int>(n); const int& r1 = ByRef<const int>(n);
EXPECT_EQ(&n, &r1); EXPECT_EQ(&n, &r1);
// ByRef<char>(n); // This shouldn't compile - we have a negative // ByRef<char>(n); // This shouldn't compile - we have a negative
// compilation test to catch it. // compilation test to catch it.
Derived d; Derived d;
Derived& r2 = ByRef<Derived>(d); Derived& r2 = ByRef<Derived>(d);
EXPECT_EQ(&d, &r2); EXPECT_EQ(&d, &r2);
const Derived& r3 = ByRef<const Derived>(d); const Derived& r3 = ByRef<const Derived>(d);
EXPECT_EQ(&d, &r3); EXPECT_EQ(&d, &r3);
Base& r4 = ByRef<Base>(d); Base& r4 = ByRef<Base>(d);
EXPECT_EQ(&d, &r4); EXPECT_EQ(&d, &r4);
skipping to change at line 1374 skipping to change at line 1795
std::unique_ptr<Base> result2 = mock.MakeUniqueBase(); std::unique_ptr<Base> result2 = mock.MakeUniqueBase();
EXPECT_EQ(d, result2.get()); EXPECT_EQ(d, result2.get());
} }
TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) { TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) {
testing::MockFunction<void()> mock_function; testing::MockFunction<void()> mock_function;
MockClass mock; MockClass mock;
std::unique_ptr<int> i(new int(19)); std::unique_ptr<int> i(new int(19));
EXPECT_CALL(mock_function, Call()); EXPECT_CALL(mock_function, Call());
EXPECT_CALL(mock, MakeUnique()).WillOnce(DoAll( EXPECT_CALL(mock, MakeUnique())
InvokeWithoutArgs(&mock_function, &testing::MockFunction<void()>::Call), .WillOnce(DoAll(InvokeWithoutArgs(&mock_function,
Return(ByMove(std::move(i))))); &testing::MockFunction<void()>::Call),
Return(ByMove(std::move(i)))));
std::unique_ptr<int> result1 = mock.MakeUnique(); std::unique_ptr<int> result1 = mock.MakeUnique();
EXPECT_EQ(19, *result1); EXPECT_EQ(19, *result1);
} }
TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) { TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
MockClass mock; MockClass mock;
// Check default value // Check default value
DefaultValue<std::unique_ptr<int>>::SetFactory([] { DefaultValue<std::unique_ptr<int>>::SetFactory(
return std::unique_ptr<int>(new int(42)); [] { return std::unique_ptr<int>(new int(42)); });
});
EXPECT_EQ(42, *mock.MakeUnique()); EXPECT_EQ(42, *mock.MakeUnique());
EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource)); EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource));
EXPECT_CALL(mock, MakeVectorUnique()) EXPECT_CALL(mock, MakeVectorUnique())
.WillRepeatedly(Invoke(VectorUniquePtrSource)); .WillRepeatedly(Invoke(VectorUniquePtrSource));
std::unique_ptr<int> result1 = mock.MakeUnique(); std::unique_ptr<int> result1 = mock.MakeUnique();
EXPECT_EQ(19, *result1); EXPECT_EQ(19, *result1);
std::unique_ptr<int> result2 = mock.MakeUnique(); std::unique_ptr<int> result2 = mock.MakeUnique();
EXPECT_EQ(19, *result2); EXPECT_EQ(19, *result2);
EXPECT_NE(result1, result2); EXPECT_NE(result1, result2);
skipping to change at line 1448 skipping to change at line 1869
// The unique_ptr can be saved by the action. // The unique_ptr can be saved by the action.
std::unique_ptr<int> saved; std::unique_ptr<int> saved;
EXPECT_CALL(mock, TakeUnique(_)).WillOnce([&saved](std::unique_ptr<int> i) { EXPECT_CALL(mock, TakeUnique(_)).WillOnce([&saved](std::unique_ptr<int> i) {
saved = std::move(i); saved = std::move(i);
return 0; return 0;
}); });
EXPECT_EQ(0, mock.TakeUnique(make(42))); EXPECT_EQ(0, mock.TakeUnique(make(42)));
EXPECT_EQ(42, *saved); EXPECT_EQ(42, *saved);
} }
// It should be possible to use callables with an &&-qualified call operator
// with WillOnce, since they will be called only once. This allows actions to
// contain and manipulate move-only types.
TEST(MockMethodTest, ActionHasRvalueRefQualifiedCallOperator) {
struct Return17 {
int operator()() && { return 17; }
};
// Action is directly compatible with mocked function type.
{
MockFunction<int()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return17());
EXPECT_EQ(17, mock.AsStdFunction()());
}
// Action doesn't want mocked function arguments.
{
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call).WillOnce(Return17());
EXPECT_EQ(17, mock.AsStdFunction()(0));
}
}
// Edge case: if an action has both a const-qualified and an &&-qualified call
// operator, there should be no "ambiguous call" errors. The &&-qualified
// operator should be used by WillOnce (since it doesn't need to retain the
// action beyond one call), and the const-qualified one by WillRepeatedly.
TEST(MockMethodTest, ActionHasMultipleCallOperators) {
struct ReturnInt {
int operator()() && { return 17; }
int operator()() const& { return 19; }
};
// Directly compatible with mocked function type.
{
MockFunction<int()> mock;
EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
EXPECT_EQ(17, mock.AsStdFunction()());
EXPECT_EQ(19, mock.AsStdFunction()());
EXPECT_EQ(19, mock.AsStdFunction()());
}
// Ignores function arguments.
{
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
EXPECT_EQ(17, mock.AsStdFunction()(0));
EXPECT_EQ(19, mock.AsStdFunction()(0));
EXPECT_EQ(19, mock.AsStdFunction()(0));
}
}
// WillOnce should have no problem coping with a move-only action, whether it is
// &&-qualified or not.
TEST(MockMethodTest, MoveOnlyAction) {
// &&-qualified
{
struct Return17 {
Return17() = default;
Return17(Return17&&) = default;
Return17(const Return17&) = delete;
Return17 operator=(const Return17&) = delete;
int operator()() && { return 17; }
};
MockFunction<int()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return17());
EXPECT_EQ(17, mock.AsStdFunction()());
}
// Not &&-qualified
{
struct Return17 {
Return17() = default;
Return17(Return17&&) = default;
Return17(const Return17&) = delete;
Return17 operator=(const Return17&) = delete;
int operator()() const { return 17; }
};
MockFunction<int()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return17());
EXPECT_EQ(17, mock.AsStdFunction()());
}
}
// It should be possible to use an action that returns a value with a mock
// function that doesn't, both through WillOnce and WillRepeatedly.
TEST(MockMethodTest, ActionReturnsIgnoredValue) {
struct ReturnInt {
int operator()() const { return 0; }
};
MockFunction<void()> mock;
EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
mock.AsStdFunction()();
mock.AsStdFunction()();
}
// Despite the fanciness around move-only actions and so on, it should still be
// possible to hand an lvalue reference to a copyable action to WillOnce.
TEST(MockMethodTest, WillOnceCanAcceptLvalueReference) {
MockFunction<int()> mock;
const auto action = [] { return 17; };
EXPECT_CALL(mock, Call).WillOnce(action);
EXPECT_EQ(17, mock.AsStdFunction()());
}
// A callable that doesn't use SFINAE to restrict its call operator's overload
// set, but is still picky about which arguments it will accept.
struct StaticAssertSingleArgument {
template <typename... Args>
static constexpr bool CheckArgs() {
static_assert(sizeof...(Args) == 1, "");
return true;
}
template <typename... Args, bool = CheckArgs<Args...>()>
int operator()(Args...) const {
return 17;
}
};
// WillOnce and WillRepeatedly should both work fine with naïve implementations
// of actions that don't use SFINAE to limit the overload set for their call
// operator. If they are compatible with the actual mocked signature, we
// shouldn't probe them with no arguments and trip a static_assert.
TEST(MockMethodTest, ActionSwallowsAllArguments) {
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(StaticAssertSingleArgument{})
.WillRepeatedly(StaticAssertSingleArgument{});
EXPECT_EQ(17, mock.AsStdFunction()(0));
EXPECT_EQ(17, mock.AsStdFunction()(0));
}
struct ActionWithTemplatedConversionOperators {
template <typename... Args>
operator OnceAction<int(Args...)>() && { // NOLINT
return [] { return 17; };
}
template <typename... Args>
operator Action<int(Args...)>() const { // NOLINT
return [] { return 19; };
}
};
// It should be fine to hand both WillOnce and WillRepeatedly a function that
// defines templated conversion operators to OnceAction and Action. WillOnce
// should prefer the OnceAction version.
TEST(MockMethodTest, ActionHasTemplatedConversionOperators) {
MockFunction<int()> mock;
EXPECT_CALL(mock, Call)
.WillOnce(ActionWithTemplatedConversionOperators{})
.WillRepeatedly(ActionWithTemplatedConversionOperators{});
EXPECT_EQ(17, mock.AsStdFunction()());
EXPECT_EQ(19, mock.AsStdFunction()());
}
// Tests for std::function based action. // Tests for std::function based action.
int Add(int val, int& ref, int* ptr) { // NOLINT int Add(int val, int& ref, int* ptr) { // NOLINT
int result = val + ref + *ptr; int result = val + ref + *ptr;
ref = 42; ref = 42;
*ptr = 43; *ptr = 43;
return result; return result;
} }
int Deref(std::unique_ptr<int> ptr) { return *ptr; } int Deref(std::unique_ptr<int> ptr) { return *ptr; }
struct Double { struct Double {
template <typename T> template <typename T>
T operator()(T t) { return 2 * t; } T operator()(T t) {
return 2 * t;
}
}; };
std::unique_ptr<int> UniqueInt(int i) { std::unique_ptr<int> UniqueInt(int i) {
return std::unique_ptr<int>(new int(i)); return std::unique_ptr<int>(new int(i));
} }
TEST(FunctorActionTest, ActionFromFunction) { TEST(FunctorActionTest, ActionFromFunction) {
Action<int(int, int&, int*)> a = &Add; Action<int(int, int&, int*)> a = &Add;
int x = 1, y = 2, z = 3; int x = 1, y = 2, z = 3;
EXPECT_EQ(6, a.Perform(std::forward_as_tuple(x, y, &z))); EXPECT_EQ(6, a.Perform(std::forward_as_tuple(x, y, &z)));
skipping to change at line 1530 skipping to change at line 2126
Action<int(int)> d = f; Action<int(int)> d = f;
f = nullptr; f = nullptr;
EXPECT_EQ(7, d.Perform(std::make_tuple(1))); EXPECT_EQ(7, d.Perform(std::make_tuple(1)));
// Ensure creation of an empty action succeeds. // Ensure creation of an empty action succeeds.
Action<void(int)>(nullptr); 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) {
[](int i, Unused, Unused) { return 2 * i; }; 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));
} }
// Test that basic built-in actions work with move-only arguments. // Test that basic built-in actions work with move-only arguments.
TEST(MoveOnlyArgumentsTest, ReturningActions) { TEST(MoveOnlyArgumentsTest, ReturningActions) {
Action<int(std::unique_ptr<int>)> a = Return(1); Action<int(std::unique_ptr<int>)> a = Return(1);
EXPECT_EQ(1, a.Perform(std::make_tuple(nullptr))); EXPECT_EQ(1, a.Perform(std::make_tuple(nullptr)));
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) { ACTION(ReturnArity) { return std::tuple_size<args_type>::value; }
return std::tuple_size<args_type>::value;
}
TEST(ActionMacro, LargeArity) { TEST(ActionMacro, LargeArity) {
EXPECT_EQ( EXPECT_EQ(
1, testing::Action<int(int)>(ReturnArity()).Perform(std::make_tuple(0))); 1, testing::Action<int(int)>(ReturnArity()).Perform(std::make_tuple(0)));
EXPECT_EQ( EXPECT_EQ(
10, 10,
testing::Action<int(int, int, int, int, int, int, int, int, int, int)>( testing::Action<int(int, int, int, int, int, int, int, int, int, int)>(
ReturnArity()) ReturnArity())
.Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); .Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)));
EXPECT_EQ( EXPECT_EQ(
20, 20,
testing::Action<int(int, int, int, int, int, int, int, int, int, int, int, testing::Action<int(int, int, int, int, int, int, int, int, int, int, int,
int, int, int, int, int, int, int, int, int)>( int, int, int, int, int, int, int, int, int)>(
ReturnArity()) ReturnArity())
.Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, .Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19))); 14, 15, 16, 17, 18, 19)));
} }
} // Unnamed namespace } // namespace
} // namespace testing
#ifdef _MSC_VER
#if _MSC_VER == 1900
# pragma warning(pop)
#endif
#endif
 End of changes. 55 change blocks. 
150 lines changed or deleted 745 lines changed or added

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