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 |