1f92157deSopenharmony_ci// Copyright 2007, Google Inc. 2f92157deSopenharmony_ci// All rights reserved. 3f92157deSopenharmony_ci// 4f92157deSopenharmony_ci// Redistribution and use in source and binary forms, with or without 5f92157deSopenharmony_ci// modification, are permitted provided that the following conditions are 6f92157deSopenharmony_ci// met: 7f92157deSopenharmony_ci// 8f92157deSopenharmony_ci// * Redistributions of source code must retain the above copyright 9f92157deSopenharmony_ci// notice, this list of conditions and the following disclaimer. 10f92157deSopenharmony_ci// * Redistributions in binary form must reproduce the above 11f92157deSopenharmony_ci// copyright notice, this list of conditions and the following disclaimer 12f92157deSopenharmony_ci// in the documentation and/or other materials provided with the 13f92157deSopenharmony_ci// distribution. 14f92157deSopenharmony_ci// * Neither the name of Google Inc. nor the names of its 15f92157deSopenharmony_ci// contributors may be used to endorse or promote products derived from 16f92157deSopenharmony_ci// this software without specific prior written permission. 17f92157deSopenharmony_ci// 18f92157deSopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19f92157deSopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20f92157deSopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21f92157deSopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22f92157deSopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23f92157deSopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24f92157deSopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25f92157deSopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26f92157deSopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27f92157deSopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28f92157deSopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29f92157deSopenharmony_ci 30f92157deSopenharmony_ci// Google Mock - a framework for writing C++ mock classes. 31f92157deSopenharmony_ci// 32f92157deSopenharmony_ci// This file tests the built-in actions. 33f92157deSopenharmony_ci 34f92157deSopenharmony_ci// Silence C4100 (unreferenced formal parameter) and C4503 (decorated name 35f92157deSopenharmony_ci// length exceeded) for MSVC. 36f92157deSopenharmony_ci#ifdef _MSC_VER 37f92157deSopenharmony_ci#pragma warning(push) 38f92157deSopenharmony_ci#pragma warning(disable : 4100) 39f92157deSopenharmony_ci#pragma warning(disable : 4503) 40f92157deSopenharmony_ci#if _MSC_VER == 1900 41f92157deSopenharmony_ci// and silence C4800 (C4800: 'int *const ': forcing value 42f92157deSopenharmony_ci// to bool 'true' or 'false') for MSVC 15 43f92157deSopenharmony_ci#pragma warning(disable : 4800) 44f92157deSopenharmony_ci#endif 45f92157deSopenharmony_ci#endif 46f92157deSopenharmony_ci 47f92157deSopenharmony_ci#include "gmock/gmock-actions.h" 48f92157deSopenharmony_ci 49f92157deSopenharmony_ci#include <algorithm> 50f92157deSopenharmony_ci#include <functional> 51f92157deSopenharmony_ci#include <iterator> 52f92157deSopenharmony_ci#include <memory> 53f92157deSopenharmony_ci#include <string> 54f92157deSopenharmony_ci#include <type_traits> 55f92157deSopenharmony_ci#include <vector> 56f92157deSopenharmony_ci 57f92157deSopenharmony_ci#include "gmock/gmock.h" 58f92157deSopenharmony_ci#include "gmock/internal/gmock-port.h" 59f92157deSopenharmony_ci#include "gtest/gtest-spi.h" 60f92157deSopenharmony_ci#include "gtest/gtest.h" 61f92157deSopenharmony_ci 62f92157deSopenharmony_cinamespace testing { 63f92157deSopenharmony_cinamespace { 64f92157deSopenharmony_ci 65f92157deSopenharmony_ciusing ::testing::internal::BuiltInDefaultValue; 66f92157deSopenharmony_ci 67f92157deSopenharmony_ciTEST(TypeTraits, Negation) { 68f92157deSopenharmony_ci // Direct use with std types. 69f92157deSopenharmony_ci static_assert(std::is_base_of<std::false_type, 70f92157deSopenharmony_ci internal::negation<std::true_type>>::value, 71f92157deSopenharmony_ci ""); 72f92157deSopenharmony_ci 73f92157deSopenharmony_ci static_assert(std::is_base_of<std::true_type, 74f92157deSopenharmony_ci internal::negation<std::false_type>>::value, 75f92157deSopenharmony_ci ""); 76f92157deSopenharmony_ci 77f92157deSopenharmony_ci // With other types that fit the requirement of a value member that is 78f92157deSopenharmony_ci // convertible to bool. 79f92157deSopenharmony_ci static_assert(std::is_base_of< 80f92157deSopenharmony_ci std::true_type, 81f92157deSopenharmony_ci internal::negation<std::integral_constant<int, 0>>>::value, 82f92157deSopenharmony_ci ""); 83f92157deSopenharmony_ci 84f92157deSopenharmony_ci static_assert(std::is_base_of< 85f92157deSopenharmony_ci std::false_type, 86f92157deSopenharmony_ci internal::negation<std::integral_constant<int, 1>>>::value, 87f92157deSopenharmony_ci ""); 88f92157deSopenharmony_ci 89f92157deSopenharmony_ci static_assert(std::is_base_of< 90f92157deSopenharmony_ci std::false_type, 91f92157deSopenharmony_ci internal::negation<std::integral_constant<int, -1>>>::value, 92f92157deSopenharmony_ci ""); 93f92157deSopenharmony_ci} 94f92157deSopenharmony_ci 95f92157deSopenharmony_ci// Weird false/true types that aren't actually bool constants (but should still 96f92157deSopenharmony_ci// be legal according to [meta.logical] because `bool(T::value)` is valid), are 97f92157deSopenharmony_ci// distinct from std::false_type and std::true_type, and are distinct from other 98f92157deSopenharmony_ci// instantiations of the same template. 99f92157deSopenharmony_ci// 100f92157deSopenharmony_ci// These let us check finicky details mandated by the standard like 101f92157deSopenharmony_ci// "std::conjunction should evaluate to a type that inherits from the first 102f92157deSopenharmony_ci// false-y input". 103f92157deSopenharmony_citemplate <int> 104f92157deSopenharmony_cistruct MyFalse : std::integral_constant<int, 0> {}; 105f92157deSopenharmony_ci 106f92157deSopenharmony_citemplate <int> 107f92157deSopenharmony_cistruct MyTrue : std::integral_constant<int, -1> {}; 108f92157deSopenharmony_ci 109f92157deSopenharmony_ciTEST(TypeTraits, Conjunction) { 110f92157deSopenharmony_ci // Base case: always true. 111f92157deSopenharmony_ci static_assert(std::is_base_of<std::true_type, internal::conjunction<>>::value, 112f92157deSopenharmony_ci ""); 113f92157deSopenharmony_ci 114f92157deSopenharmony_ci // One predicate: inherits from that predicate, regardless of value. 115f92157deSopenharmony_ci static_assert( 116f92157deSopenharmony_ci std::is_base_of<MyFalse<0>, internal::conjunction<MyFalse<0>>>::value, 117f92157deSopenharmony_ci ""); 118f92157deSopenharmony_ci 119f92157deSopenharmony_ci static_assert( 120f92157deSopenharmony_ci std::is_base_of<MyTrue<0>, internal::conjunction<MyTrue<0>>>::value, ""); 121f92157deSopenharmony_ci 122f92157deSopenharmony_ci // Multiple predicates, with at least one false: inherits from that one. 123f92157deSopenharmony_ci static_assert( 124f92157deSopenharmony_ci std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, 125f92157deSopenharmony_ci MyTrue<2>>>::value, 126f92157deSopenharmony_ci ""); 127f92157deSopenharmony_ci 128f92157deSopenharmony_ci static_assert( 129f92157deSopenharmony_ci std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, 130f92157deSopenharmony_ci MyFalse<2>>>::value, 131f92157deSopenharmony_ci ""); 132f92157deSopenharmony_ci 133f92157deSopenharmony_ci // Short circuiting: in the case above, additional predicates need not even 134f92157deSopenharmony_ci // define a value member. 135f92157deSopenharmony_ci struct Empty {}; 136f92157deSopenharmony_ci static_assert( 137f92157deSopenharmony_ci std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, 138f92157deSopenharmony_ci Empty>>::value, 139f92157deSopenharmony_ci ""); 140f92157deSopenharmony_ci 141f92157deSopenharmony_ci // All predicates true: inherits from the last. 142f92157deSopenharmony_ci static_assert( 143f92157deSopenharmony_ci std::is_base_of<MyTrue<2>, internal::conjunction<MyTrue<0>, MyTrue<1>, 144f92157deSopenharmony_ci MyTrue<2>>>::value, 145f92157deSopenharmony_ci ""); 146f92157deSopenharmony_ci} 147f92157deSopenharmony_ci 148f92157deSopenharmony_ciTEST(TypeTraits, Disjunction) { 149f92157deSopenharmony_ci // Base case: always false. 150f92157deSopenharmony_ci static_assert( 151f92157deSopenharmony_ci std::is_base_of<std::false_type, internal::disjunction<>>::value, ""); 152f92157deSopenharmony_ci 153f92157deSopenharmony_ci // One predicate: inherits from that predicate, regardless of value. 154f92157deSopenharmony_ci static_assert( 155f92157deSopenharmony_ci std::is_base_of<MyFalse<0>, internal::disjunction<MyFalse<0>>>::value, 156f92157deSopenharmony_ci ""); 157f92157deSopenharmony_ci 158f92157deSopenharmony_ci static_assert( 159f92157deSopenharmony_ci std::is_base_of<MyTrue<0>, internal::disjunction<MyTrue<0>>>::value, ""); 160f92157deSopenharmony_ci 161f92157deSopenharmony_ci // Multiple predicates, with at least one true: inherits from that one. 162f92157deSopenharmony_ci static_assert( 163f92157deSopenharmony_ci std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, 164f92157deSopenharmony_ci MyFalse<2>>>::value, 165f92157deSopenharmony_ci ""); 166f92157deSopenharmony_ci 167f92157deSopenharmony_ci static_assert( 168f92157deSopenharmony_ci std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, 169f92157deSopenharmony_ci MyTrue<2>>>::value, 170f92157deSopenharmony_ci ""); 171f92157deSopenharmony_ci 172f92157deSopenharmony_ci // Short circuiting: in the case above, additional predicates need not even 173f92157deSopenharmony_ci // define a value member. 174f92157deSopenharmony_ci struct Empty {}; 175f92157deSopenharmony_ci static_assert( 176f92157deSopenharmony_ci std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, 177f92157deSopenharmony_ci Empty>>::value, 178f92157deSopenharmony_ci ""); 179f92157deSopenharmony_ci 180f92157deSopenharmony_ci // All predicates false: inherits from the last. 181f92157deSopenharmony_ci static_assert( 182f92157deSopenharmony_ci std::is_base_of<MyFalse<2>, internal::disjunction<MyFalse<0>, MyFalse<1>, 183f92157deSopenharmony_ci MyFalse<2>>>::value, 184f92157deSopenharmony_ci ""); 185f92157deSopenharmony_ci} 186f92157deSopenharmony_ci 187f92157deSopenharmony_ciTEST(TypeTraits, IsInvocableRV) { 188f92157deSopenharmony_ci struct C { 189f92157deSopenharmony_ci int operator()() const { return 0; } 190f92157deSopenharmony_ci void operator()(int) & {} 191f92157deSopenharmony_ci std::string operator()(int) && { return ""; }; 192f92157deSopenharmony_ci }; 193f92157deSopenharmony_ci 194f92157deSopenharmony_ci // The first overload is callable for const and non-const rvalues and lvalues. 195f92157deSopenharmony_ci // It can be used to obtain an int, cv void, or anything int is convertible 196f92157deSopenharmony_ci // to. 197f92157deSopenharmony_ci static_assert(internal::is_callable_r<int, C>::value, ""); 198f92157deSopenharmony_ci static_assert(internal::is_callable_r<int, C&>::value, ""); 199f92157deSopenharmony_ci static_assert(internal::is_callable_r<int, const C>::value, ""); 200f92157deSopenharmony_ci static_assert(internal::is_callable_r<int, const C&>::value, ""); 201f92157deSopenharmony_ci 202f92157deSopenharmony_ci static_assert(internal::is_callable_r<void, C>::value, ""); 203f92157deSopenharmony_ci static_assert(internal::is_callable_r<const volatile void, C>::value, ""); 204f92157deSopenharmony_ci static_assert(internal::is_callable_r<char, C>::value, ""); 205f92157deSopenharmony_ci 206f92157deSopenharmony_ci // It's possible to provide an int. If it's given to an lvalue, the result is 207f92157deSopenharmony_ci // void. Otherwise it is std::string (which is also treated as allowed for a 208f92157deSopenharmony_ci // void result type). 209f92157deSopenharmony_ci static_assert(internal::is_callable_r<void, C&, int>::value, ""); 210f92157deSopenharmony_ci static_assert(!internal::is_callable_r<int, C&, int>::value, ""); 211f92157deSopenharmony_ci static_assert(!internal::is_callable_r<std::string, C&, int>::value, ""); 212f92157deSopenharmony_ci static_assert(!internal::is_callable_r<void, const C&, int>::value, ""); 213f92157deSopenharmony_ci 214f92157deSopenharmony_ci static_assert(internal::is_callable_r<std::string, C, int>::value, ""); 215f92157deSopenharmony_ci static_assert(internal::is_callable_r<void, C, int>::value, ""); 216f92157deSopenharmony_ci static_assert(!internal::is_callable_r<int, C, int>::value, ""); 217f92157deSopenharmony_ci 218f92157deSopenharmony_ci // It's not possible to provide other arguments. 219f92157deSopenharmony_ci static_assert(!internal::is_callable_r<void, C, std::string>::value, ""); 220f92157deSopenharmony_ci static_assert(!internal::is_callable_r<void, C, int, int>::value, ""); 221f92157deSopenharmony_ci 222f92157deSopenharmony_ci // In C++17 and above, where it's guaranteed that functions can return 223f92157deSopenharmony_ci // non-moveable objects, everything should work fine for non-moveable rsult 224f92157deSopenharmony_ci // types too. 225f92157deSopenharmony_ci#if defined(__cplusplus) && __cplusplus >= 201703L 226f92157deSopenharmony_ci { 227f92157deSopenharmony_ci struct NonMoveable { 228f92157deSopenharmony_ci NonMoveable() = default; 229f92157deSopenharmony_ci NonMoveable(NonMoveable&&) = delete; 230f92157deSopenharmony_ci }; 231f92157deSopenharmony_ci 232f92157deSopenharmony_ci static_assert(!std::is_move_constructible_v<NonMoveable>); 233f92157deSopenharmony_ci 234f92157deSopenharmony_ci struct Callable { 235f92157deSopenharmony_ci NonMoveable operator()() { return NonMoveable(); } 236f92157deSopenharmony_ci }; 237f92157deSopenharmony_ci 238f92157deSopenharmony_ci static_assert(internal::is_callable_r<NonMoveable, Callable>::value); 239f92157deSopenharmony_ci static_assert(internal::is_callable_r<void, Callable>::value); 240f92157deSopenharmony_ci static_assert( 241f92157deSopenharmony_ci internal::is_callable_r<const volatile void, Callable>::value); 242f92157deSopenharmony_ci 243f92157deSopenharmony_ci static_assert(!internal::is_callable_r<int, Callable>::value); 244f92157deSopenharmony_ci static_assert(!internal::is_callable_r<NonMoveable, Callable, int>::value); 245f92157deSopenharmony_ci } 246f92157deSopenharmony_ci#endif // C++17 and above 247f92157deSopenharmony_ci 248f92157deSopenharmony_ci // Nothing should choke when we try to call other arguments besides directly 249f92157deSopenharmony_ci // callable objects, but they should not show up as callable. 250f92157deSopenharmony_ci static_assert(!internal::is_callable_r<void, int>::value, ""); 251f92157deSopenharmony_ci static_assert(!internal::is_callable_r<void, void (C::*)()>::value, ""); 252f92157deSopenharmony_ci static_assert(!internal::is_callable_r<void, void (C::*)(), C*>::value, ""); 253f92157deSopenharmony_ci} 254f92157deSopenharmony_ci 255f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<T*>::Get() returns NULL. 256f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, IsNullForPointerTypes) { 257f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == nullptr); 258f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == nullptr); 259f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == nullptr); 260f92157deSopenharmony_ci} 261f92157deSopenharmony_ci 262f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<T*>::Exists() return true. 263f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, ExistsForPointerTypes) { 264f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<int*>::Exists()); 265f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<const char*>::Exists()); 266f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<void*>::Exists()); 267f92157deSopenharmony_ci} 268f92157deSopenharmony_ci 269f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<T>::Get() returns 0 when T is a 270f92157deSopenharmony_ci// built-in numeric type. 271f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) { 272f92157deSopenharmony_ci EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get()); 273f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get()); 274f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<char>::Get()); 275f92157deSopenharmony_ci#if GMOCK_WCHAR_T_IS_NATIVE_ 276f92157deSopenharmony_ci#if !defined(__WCHAR_UNSIGNED__) 277f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get()); 278f92157deSopenharmony_ci#else 279f92157deSopenharmony_ci EXPECT_EQ(0U, BuiltInDefaultValue<wchar_t>::Get()); 280f92157deSopenharmony_ci#endif 281f92157deSopenharmony_ci#endif 282f92157deSopenharmony_ci EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT 283f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT 284f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT 285f92157deSopenharmony_ci EXPECT_EQ(0U, BuiltInDefaultValue<unsigned int>::Get()); 286f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get()); 287f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<int>::Get()); 288f92157deSopenharmony_ci EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT 289f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT 290f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT 291f92157deSopenharmony_ci EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long long>::Get()); // NOLINT 292f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<signed long long>::Get()); // NOLINT 293f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<long long>::Get()); // NOLINT 294f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<float>::Get()); 295f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<double>::Get()); 296f92157deSopenharmony_ci} 297f92157deSopenharmony_ci 298f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a 299f92157deSopenharmony_ci// built-in numeric type. 300f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, ExistsForNumericTypes) { 301f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists()); 302f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists()); 303f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<char>::Exists()); 304f92157deSopenharmony_ci#if GMOCK_WCHAR_T_IS_NATIVE_ 305f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists()); 306f92157deSopenharmony_ci#endif 307f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT 308f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<signed short>::Exists()); // NOLINT 309f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<short>::Exists()); // NOLINT 310f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<unsigned int>::Exists()); 311f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<signed int>::Exists()); 312f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<int>::Exists()); 313f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<unsigned long>::Exists()); // NOLINT 314f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<signed long>::Exists()); // NOLINT 315f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<long>::Exists()); // NOLINT 316f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<unsigned long long>::Exists()); // NOLINT 317f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<signed long long>::Exists()); // NOLINT 318f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<long long>::Exists()); // NOLINT 319f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<float>::Exists()); 320f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<double>::Exists()); 321f92157deSopenharmony_ci} 322f92157deSopenharmony_ci 323f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<bool>::Get() returns false. 324f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, IsFalseForBool) { 325f92157deSopenharmony_ci EXPECT_FALSE(BuiltInDefaultValue<bool>::Get()); 326f92157deSopenharmony_ci} 327f92157deSopenharmony_ci 328f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<bool>::Exists() returns true. 329f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, BoolExists) { 330f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<bool>::Exists()); 331f92157deSopenharmony_ci} 332f92157deSopenharmony_ci 333f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a 334f92157deSopenharmony_ci// string type. 335f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, IsEmptyStringForString) { 336f92157deSopenharmony_ci EXPECT_EQ("", BuiltInDefaultValue<::std::string>::Get()); 337f92157deSopenharmony_ci} 338f92157deSopenharmony_ci 339f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a 340f92157deSopenharmony_ci// string type. 341f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, ExistsForString) { 342f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<::std::string>::Exists()); 343f92157deSopenharmony_ci} 344f92157deSopenharmony_ci 345f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<const T>::Get() returns the same 346f92157deSopenharmony_ci// value as BuiltInDefaultValue<T>::Get() does. 347f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, WorksForConstTypes) { 348f92157deSopenharmony_ci EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get()); 349f92157deSopenharmony_ci EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get()); 350f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == nullptr); 351f92157deSopenharmony_ci EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get()); 352f92157deSopenharmony_ci} 353f92157deSopenharmony_ci 354f92157deSopenharmony_ci// A type that's default constructible. 355f92157deSopenharmony_ciclass MyDefaultConstructible { 356f92157deSopenharmony_ci public: 357f92157deSopenharmony_ci MyDefaultConstructible() : value_(42) {} 358f92157deSopenharmony_ci 359f92157deSopenharmony_ci int value() const { return value_; } 360f92157deSopenharmony_ci 361f92157deSopenharmony_ci private: 362f92157deSopenharmony_ci int value_; 363f92157deSopenharmony_ci}; 364f92157deSopenharmony_ci 365f92157deSopenharmony_ci// A type that's not default constructible. 366f92157deSopenharmony_ciclass MyNonDefaultConstructible { 367f92157deSopenharmony_ci public: 368f92157deSopenharmony_ci // Does not have a default ctor. 369f92157deSopenharmony_ci explicit MyNonDefaultConstructible(int a_value) : value_(a_value) {} 370f92157deSopenharmony_ci 371f92157deSopenharmony_ci int value() const { return value_; } 372f92157deSopenharmony_ci 373f92157deSopenharmony_ci private: 374f92157deSopenharmony_ci int value_; 375f92157deSopenharmony_ci}; 376f92157deSopenharmony_ci 377f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, ExistsForDefaultConstructibleType) { 378f92157deSopenharmony_ci EXPECT_TRUE(BuiltInDefaultValue<MyDefaultConstructible>::Exists()); 379f92157deSopenharmony_ci} 380f92157deSopenharmony_ci 381f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, IsDefaultConstructedForDefaultConstructibleType) { 382f92157deSopenharmony_ci EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value()); 383f92157deSopenharmony_ci} 384f92157deSopenharmony_ci 385f92157deSopenharmony_ciTEST(BuiltInDefaultValueTest, DoesNotExistForNonDefaultConstructibleType) { 386f92157deSopenharmony_ci EXPECT_FALSE(BuiltInDefaultValue<MyNonDefaultConstructible>::Exists()); 387f92157deSopenharmony_ci} 388f92157deSopenharmony_ci 389f92157deSopenharmony_ci// Tests that BuiltInDefaultValue<T&>::Get() aborts the program. 390f92157deSopenharmony_ciTEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) { 391f92157deSopenharmony_ci EXPECT_DEATH_IF_SUPPORTED({ BuiltInDefaultValue<int&>::Get(); }, ""); 392f92157deSopenharmony_ci EXPECT_DEATH_IF_SUPPORTED({ BuiltInDefaultValue<const char&>::Get(); }, ""); 393f92157deSopenharmony_ci} 394f92157deSopenharmony_ci 395f92157deSopenharmony_ciTEST(BuiltInDefaultValueDeathTest, IsUndefinedForNonDefaultConstructibleType) { 396f92157deSopenharmony_ci EXPECT_DEATH_IF_SUPPORTED( 397f92157deSopenharmony_ci { BuiltInDefaultValue<MyNonDefaultConstructible>::Get(); }, ""); 398f92157deSopenharmony_ci} 399f92157deSopenharmony_ci 400f92157deSopenharmony_ci// Tests that DefaultValue<T>::IsSet() is false initially. 401f92157deSopenharmony_ciTEST(DefaultValueTest, IsInitiallyUnset) { 402f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<int>::IsSet()); 403f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyDefaultConstructible>::IsSet()); 404f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::IsSet()); 405f92157deSopenharmony_ci} 406f92157deSopenharmony_ci 407f92157deSopenharmony_ci// Tests that DefaultValue<T> can be set and then unset. 408f92157deSopenharmony_ciTEST(DefaultValueTest, CanBeSetAndUnset) { 409f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<int>::Exists()); 410f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::Exists()); 411f92157deSopenharmony_ci 412f92157deSopenharmony_ci DefaultValue<int>::Set(1); 413f92157deSopenharmony_ci DefaultValue<const MyNonDefaultConstructible>::Set( 414f92157deSopenharmony_ci MyNonDefaultConstructible(42)); 415f92157deSopenharmony_ci 416f92157deSopenharmony_ci EXPECT_EQ(1, DefaultValue<int>::Get()); 417f92157deSopenharmony_ci EXPECT_EQ(42, DefaultValue<const MyNonDefaultConstructible>::Get().value()); 418f92157deSopenharmony_ci 419f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<int>::Exists()); 420f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<const MyNonDefaultConstructible>::Exists()); 421f92157deSopenharmony_ci 422f92157deSopenharmony_ci DefaultValue<int>::Clear(); 423f92157deSopenharmony_ci DefaultValue<const MyNonDefaultConstructible>::Clear(); 424f92157deSopenharmony_ci 425f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<int>::IsSet()); 426f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::IsSet()); 427f92157deSopenharmony_ci 428f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<int>::Exists()); 429f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::Exists()); 430f92157deSopenharmony_ci} 431f92157deSopenharmony_ci 432f92157deSopenharmony_ci// Tests that DefaultValue<T>::Get() returns the 433f92157deSopenharmony_ci// BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is 434f92157deSopenharmony_ci// false. 435f92157deSopenharmony_ciTEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) { 436f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<int>::IsSet()); 437f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<int>::Exists()); 438f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::IsSet()); 439f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::Exists()); 440f92157deSopenharmony_ci 441f92157deSopenharmony_ci EXPECT_EQ(0, DefaultValue<int>::Get()); 442f92157deSopenharmony_ci 443f92157deSopenharmony_ci EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); }, 444f92157deSopenharmony_ci ""); 445f92157deSopenharmony_ci} 446f92157deSopenharmony_ci 447f92157deSopenharmony_ciTEST(DefaultValueTest, GetWorksForMoveOnlyIfSet) { 448f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists()); 449f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == nullptr); 450f92157deSopenharmony_ci DefaultValue<std::unique_ptr<int>>::SetFactory( 451f92157deSopenharmony_ci [] { return std::unique_ptr<int>(new int(42)); }); 452f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists()); 453f92157deSopenharmony_ci std::unique_ptr<int> i = DefaultValue<std::unique_ptr<int>>::Get(); 454f92157deSopenharmony_ci EXPECT_EQ(42, *i); 455f92157deSopenharmony_ci} 456f92157deSopenharmony_ci 457f92157deSopenharmony_ci// Tests that DefaultValue<void>::Get() returns void. 458f92157deSopenharmony_ciTEST(DefaultValueTest, GetWorksForVoid) { return DefaultValue<void>::Get(); } 459f92157deSopenharmony_ci 460f92157deSopenharmony_ci// Tests using DefaultValue with a reference type. 461f92157deSopenharmony_ci 462f92157deSopenharmony_ci// Tests that DefaultValue<T&>::IsSet() is false initially. 463f92157deSopenharmony_ciTEST(DefaultValueOfReferenceTest, IsInitiallyUnset) { 464f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<int&>::IsSet()); 465f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::IsSet()); 466f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet()); 467f92157deSopenharmony_ci} 468f92157deSopenharmony_ci 469f92157deSopenharmony_ci// Tests that DefaultValue<T&>::Exists is false initially. 470f92157deSopenharmony_ciTEST(DefaultValueOfReferenceTest, IsInitiallyNotExisting) { 471f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<int&>::Exists()); 472f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::Exists()); 473f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::Exists()); 474f92157deSopenharmony_ci} 475f92157deSopenharmony_ci 476f92157deSopenharmony_ci// Tests that DefaultValue<T&> can be set and then unset. 477f92157deSopenharmony_ciTEST(DefaultValueOfReferenceTest, CanBeSetAndUnset) { 478f92157deSopenharmony_ci int n = 1; 479f92157deSopenharmony_ci DefaultValue<const int&>::Set(n); 480f92157deSopenharmony_ci MyNonDefaultConstructible x(42); 481f92157deSopenharmony_ci DefaultValue<MyNonDefaultConstructible&>::Set(x); 482f92157deSopenharmony_ci 483f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<const int&>::Exists()); 484f92157deSopenharmony_ci EXPECT_TRUE(DefaultValue<MyNonDefaultConstructible&>::Exists()); 485f92157deSopenharmony_ci 486f92157deSopenharmony_ci EXPECT_EQ(&n, &(DefaultValue<const int&>::Get())); 487f92157deSopenharmony_ci EXPECT_EQ(&x, &(DefaultValue<MyNonDefaultConstructible&>::Get())); 488f92157deSopenharmony_ci 489f92157deSopenharmony_ci DefaultValue<const int&>::Clear(); 490f92157deSopenharmony_ci DefaultValue<MyNonDefaultConstructible&>::Clear(); 491f92157deSopenharmony_ci 492f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<const int&>::Exists()); 493f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::Exists()); 494f92157deSopenharmony_ci 495f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<const int&>::IsSet()); 496f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet()); 497f92157deSopenharmony_ci} 498f92157deSopenharmony_ci 499f92157deSopenharmony_ci// Tests that DefaultValue<T&>::Get() returns the 500f92157deSopenharmony_ci// BuiltInDefaultValue<T&>::Get() when DefaultValue<T&>::IsSet() is 501f92157deSopenharmony_ci// false. 502f92157deSopenharmony_ciTEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) { 503f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<int&>::IsSet()); 504f92157deSopenharmony_ci EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet()); 505f92157deSopenharmony_ci 506f92157deSopenharmony_ci EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<int&>::Get(); }, ""); 507f92157deSopenharmony_ci EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); }, 508f92157deSopenharmony_ci ""); 509f92157deSopenharmony_ci} 510f92157deSopenharmony_ci 511f92157deSopenharmony_ci// Tests that ActionInterface can be implemented by defining the 512f92157deSopenharmony_ci// Perform method. 513f92157deSopenharmony_ci 514f92157deSopenharmony_citypedef int MyGlobalFunction(bool, int); 515f92157deSopenharmony_ci 516f92157deSopenharmony_ciclass MyActionImpl : public ActionInterface<MyGlobalFunction> { 517f92157deSopenharmony_ci public: 518f92157deSopenharmony_ci int Perform(const std::tuple<bool, int>& args) override { 519f92157deSopenharmony_ci return std::get<0>(args) ? std::get<1>(args) : 0; 520f92157deSopenharmony_ci } 521f92157deSopenharmony_ci}; 522f92157deSopenharmony_ci 523f92157deSopenharmony_ciTEST(ActionInterfaceTest, CanBeImplementedByDefiningPerform) { 524f92157deSopenharmony_ci MyActionImpl my_action_impl; 525f92157deSopenharmony_ci (void)my_action_impl; 526f92157deSopenharmony_ci} 527f92157deSopenharmony_ci 528f92157deSopenharmony_ciTEST(ActionInterfaceTest, MakeAction) { 529f92157deSopenharmony_ci Action<MyGlobalFunction> action = MakeAction(new MyActionImpl); 530f92157deSopenharmony_ci 531f92157deSopenharmony_ci // When exercising the Perform() method of Action<F>, we must pass 532f92157deSopenharmony_ci // it a tuple whose size and type are compatible with F's argument 533f92157deSopenharmony_ci // types. For example, if F is int(), then Perform() takes a 534f92157deSopenharmony_ci // 0-tuple; if F is void(bool, int), then Perform() takes a 535f92157deSopenharmony_ci // std::tuple<bool, int>, and so on. 536f92157deSopenharmony_ci EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5))); 537f92157deSopenharmony_ci} 538f92157deSopenharmony_ci 539f92157deSopenharmony_ci// Tests that Action<F> can be constructed from a pointer to 540f92157deSopenharmony_ci// ActionInterface<F>. 541f92157deSopenharmony_ciTEST(ActionTest, CanBeConstructedFromActionInterface) { 542f92157deSopenharmony_ci Action<MyGlobalFunction> action(new MyActionImpl); 543f92157deSopenharmony_ci} 544f92157deSopenharmony_ci 545f92157deSopenharmony_ci// Tests that Action<F> delegates actual work to ActionInterface<F>. 546f92157deSopenharmony_ciTEST(ActionTest, DelegatesWorkToActionInterface) { 547f92157deSopenharmony_ci const Action<MyGlobalFunction> action(new MyActionImpl); 548f92157deSopenharmony_ci 549f92157deSopenharmony_ci EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5))); 550f92157deSopenharmony_ci EXPECT_EQ(0, action.Perform(std::make_tuple(false, 1))); 551f92157deSopenharmony_ci} 552f92157deSopenharmony_ci 553f92157deSopenharmony_ci// Tests that Action<F> can be copied. 554f92157deSopenharmony_ciTEST(ActionTest, IsCopyable) { 555f92157deSopenharmony_ci Action<MyGlobalFunction> a1(new MyActionImpl); 556f92157deSopenharmony_ci Action<MyGlobalFunction> a2(a1); // Tests the copy constructor. 557f92157deSopenharmony_ci 558f92157deSopenharmony_ci // a1 should continue to work after being copied from. 559f92157deSopenharmony_ci EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5))); 560f92157deSopenharmony_ci EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 1))); 561f92157deSopenharmony_ci 562f92157deSopenharmony_ci // a2 should work like the action it was copied from. 563f92157deSopenharmony_ci EXPECT_EQ(5, a2.Perform(std::make_tuple(true, 5))); 564f92157deSopenharmony_ci EXPECT_EQ(0, a2.Perform(std::make_tuple(false, 1))); 565f92157deSopenharmony_ci 566f92157deSopenharmony_ci a2 = a1; // Tests the assignment operator. 567f92157deSopenharmony_ci 568f92157deSopenharmony_ci // a1 should continue to work after being copied from. 569f92157deSopenharmony_ci EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5))); 570f92157deSopenharmony_ci EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 1))); 571f92157deSopenharmony_ci 572f92157deSopenharmony_ci // a2 should work like the action it was copied from. 573f92157deSopenharmony_ci EXPECT_EQ(5, a2.Perform(std::make_tuple(true, 5))); 574f92157deSopenharmony_ci EXPECT_EQ(0, a2.Perform(std::make_tuple(false, 1))); 575f92157deSopenharmony_ci} 576f92157deSopenharmony_ci 577f92157deSopenharmony_ci// Tests that an Action<From> object can be converted to a 578f92157deSopenharmony_ci// compatible Action<To> object. 579f92157deSopenharmony_ci 580f92157deSopenharmony_ciclass IsNotZero : public ActionInterface<bool(int)> { // NOLINT 581f92157deSopenharmony_ci public: 582f92157deSopenharmony_ci bool Perform(const std::tuple<int>& arg) override { 583f92157deSopenharmony_ci return std::get<0>(arg) != 0; 584f92157deSopenharmony_ci } 585f92157deSopenharmony_ci}; 586f92157deSopenharmony_ci 587f92157deSopenharmony_ciTEST(ActionTest, CanBeConvertedToOtherActionType) { 588f92157deSopenharmony_ci const Action<bool(int)> a1(new IsNotZero); // NOLINT 589f92157deSopenharmony_ci const Action<int(char)> a2 = Action<int(char)>(a1); // NOLINT 590f92157deSopenharmony_ci EXPECT_EQ(1, a2.Perform(std::make_tuple('a'))); 591f92157deSopenharmony_ci EXPECT_EQ(0, a2.Perform(std::make_tuple('\0'))); 592f92157deSopenharmony_ci} 593f92157deSopenharmony_ci 594f92157deSopenharmony_ci// The following two classes are for testing MakePolymorphicAction(). 595f92157deSopenharmony_ci 596f92157deSopenharmony_ci// Implements a polymorphic action that returns the second of the 597f92157deSopenharmony_ci// arguments it receives. 598f92157deSopenharmony_ciclass ReturnSecondArgumentAction { 599f92157deSopenharmony_ci public: 600f92157deSopenharmony_ci // We want to verify that MakePolymorphicAction() can work with a 601f92157deSopenharmony_ci // polymorphic action whose Perform() method template is either 602f92157deSopenharmony_ci // const or not. This lets us verify the non-const case. 603f92157deSopenharmony_ci template <typename Result, typename ArgumentTuple> 604f92157deSopenharmony_ci Result Perform(const ArgumentTuple& args) { 605f92157deSopenharmony_ci return std::get<1>(args); 606f92157deSopenharmony_ci } 607f92157deSopenharmony_ci}; 608f92157deSopenharmony_ci 609f92157deSopenharmony_ci// Implements a polymorphic action that can be used in a nullary 610f92157deSopenharmony_ci// function to return 0. 611f92157deSopenharmony_ciclass ReturnZeroFromNullaryFunctionAction { 612f92157deSopenharmony_ci public: 613f92157deSopenharmony_ci // For testing that MakePolymorphicAction() works when the 614f92157deSopenharmony_ci // implementation class' Perform() method template takes only one 615f92157deSopenharmony_ci // template parameter. 616f92157deSopenharmony_ci // 617f92157deSopenharmony_ci // We want to verify that MakePolymorphicAction() can work with a 618f92157deSopenharmony_ci // polymorphic action whose Perform() method template is either 619f92157deSopenharmony_ci // const or not. This lets us verify the const case. 620f92157deSopenharmony_ci template <typename Result> 621f92157deSopenharmony_ci Result Perform(const std::tuple<>&) const { 622f92157deSopenharmony_ci return 0; 623f92157deSopenharmony_ci } 624f92157deSopenharmony_ci}; 625f92157deSopenharmony_ci 626f92157deSopenharmony_ci// These functions verify that MakePolymorphicAction() returns a 627f92157deSopenharmony_ci// PolymorphicAction<T> where T is the argument's type. 628f92157deSopenharmony_ci 629f92157deSopenharmony_ciPolymorphicAction<ReturnSecondArgumentAction> ReturnSecondArgument() { 630f92157deSopenharmony_ci return MakePolymorphicAction(ReturnSecondArgumentAction()); 631f92157deSopenharmony_ci} 632f92157deSopenharmony_ci 633f92157deSopenharmony_ciPolymorphicAction<ReturnZeroFromNullaryFunctionAction> 634f92157deSopenharmony_ciReturnZeroFromNullaryFunction() { 635f92157deSopenharmony_ci return MakePolymorphicAction(ReturnZeroFromNullaryFunctionAction()); 636f92157deSopenharmony_ci} 637f92157deSopenharmony_ci 638f92157deSopenharmony_ci// Tests that MakePolymorphicAction() turns a polymorphic action 639f92157deSopenharmony_ci// implementation class into a polymorphic action. 640f92157deSopenharmony_ciTEST(MakePolymorphicActionTest, ConstructsActionFromImpl) { 641f92157deSopenharmony_ci Action<int(bool, int, double)> a1 = ReturnSecondArgument(); // NOLINT 642f92157deSopenharmony_ci EXPECT_EQ(5, a1.Perform(std::make_tuple(false, 5, 2.0))); 643f92157deSopenharmony_ci} 644f92157deSopenharmony_ci 645f92157deSopenharmony_ci// Tests that MakePolymorphicAction() works when the implementation 646f92157deSopenharmony_ci// class' Perform() method template has only one template parameter. 647f92157deSopenharmony_ciTEST(MakePolymorphicActionTest, WorksWhenPerformHasOneTemplateParameter) { 648f92157deSopenharmony_ci Action<int()> a1 = ReturnZeroFromNullaryFunction(); 649f92157deSopenharmony_ci EXPECT_EQ(0, a1.Perform(std::make_tuple())); 650f92157deSopenharmony_ci 651f92157deSopenharmony_ci Action<void*()> a2 = ReturnZeroFromNullaryFunction(); 652f92157deSopenharmony_ci EXPECT_TRUE(a2.Perform(std::make_tuple()) == nullptr); 653f92157deSopenharmony_ci} 654f92157deSopenharmony_ci 655f92157deSopenharmony_ci// Tests that Return() works as an action for void-returning 656f92157deSopenharmony_ci// functions. 657f92157deSopenharmony_ciTEST(ReturnTest, WorksForVoid) { 658f92157deSopenharmony_ci const Action<void(int)> ret = Return(); // NOLINT 659f92157deSopenharmony_ci return ret.Perform(std::make_tuple(1)); 660f92157deSopenharmony_ci} 661f92157deSopenharmony_ci 662f92157deSopenharmony_ci// Tests that Return(v) returns v. 663f92157deSopenharmony_ciTEST(ReturnTest, ReturnsGivenValue) { 664f92157deSopenharmony_ci Action<int()> ret = Return(1); // NOLINT 665f92157deSopenharmony_ci EXPECT_EQ(1, ret.Perform(std::make_tuple())); 666f92157deSopenharmony_ci 667f92157deSopenharmony_ci ret = Return(-5); 668f92157deSopenharmony_ci EXPECT_EQ(-5, ret.Perform(std::make_tuple())); 669f92157deSopenharmony_ci} 670f92157deSopenharmony_ci 671f92157deSopenharmony_ci// Tests that Return("string literal") works. 672f92157deSopenharmony_ciTEST(ReturnTest, AcceptsStringLiteral) { 673f92157deSopenharmony_ci Action<const char*()> a1 = Return("Hello"); 674f92157deSopenharmony_ci EXPECT_STREQ("Hello", a1.Perform(std::make_tuple())); 675f92157deSopenharmony_ci 676f92157deSopenharmony_ci Action<std::string()> a2 = Return("world"); 677f92157deSopenharmony_ci EXPECT_EQ("world", a2.Perform(std::make_tuple())); 678f92157deSopenharmony_ci} 679f92157deSopenharmony_ci 680f92157deSopenharmony_ci// Return(x) should work fine when the mock function's return type is a 681f92157deSopenharmony_ci// reference-like wrapper for decltype(x), as when x is a std::string and the 682f92157deSopenharmony_ci// mock function returns std::string_view. 683f92157deSopenharmony_ciTEST(ReturnTest, SupportsReferenceLikeReturnType) { 684f92157deSopenharmony_ci // A reference wrapper for std::vector<int>, implicitly convertible from it. 685f92157deSopenharmony_ci struct Result { 686f92157deSopenharmony_ci const std::vector<int>* v; 687f92157deSopenharmony_ci Result(const std::vector<int>& vec) : v(&vec) {} // NOLINT 688f92157deSopenharmony_ci }; 689f92157deSopenharmony_ci 690f92157deSopenharmony_ci // Set up an action for a mock function that returns the reference wrapper 691f92157deSopenharmony_ci // type, initializing it with an actual vector. 692f92157deSopenharmony_ci // 693f92157deSopenharmony_ci // The returned wrapper should be initialized with a copy of that vector 694f92157deSopenharmony_ci // that's embedded within the action itself (which should stay alive as long 695f92157deSopenharmony_ci // as the mock object is alive), rather than e.g. a reference to the temporary 696f92157deSopenharmony_ci // we feed to Return. This should work fine both for WillOnce and 697f92157deSopenharmony_ci // WillRepeatedly. 698f92157deSopenharmony_ci MockFunction<Result()> mock; 699f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 700f92157deSopenharmony_ci .WillOnce(Return(std::vector<int>{17, 19, 23})) 701f92157deSopenharmony_ci .WillRepeatedly(Return(std::vector<int>{29, 31, 37})); 702f92157deSopenharmony_ci 703f92157deSopenharmony_ci EXPECT_THAT(mock.AsStdFunction()(), 704f92157deSopenharmony_ci Field(&Result::v, Pointee(ElementsAre(17, 19, 23)))); 705f92157deSopenharmony_ci 706f92157deSopenharmony_ci EXPECT_THAT(mock.AsStdFunction()(), 707f92157deSopenharmony_ci Field(&Result::v, Pointee(ElementsAre(29, 31, 37)))); 708f92157deSopenharmony_ci} 709f92157deSopenharmony_ci 710f92157deSopenharmony_ciTEST(ReturnTest, PrefersConversionOperator) { 711f92157deSopenharmony_ci // Define types In and Out such that: 712f92157deSopenharmony_ci // 713f92157deSopenharmony_ci // * In is implicitly convertible to Out. 714f92157deSopenharmony_ci // * Out also has an explicit constructor from In. 715f92157deSopenharmony_ci // 716f92157deSopenharmony_ci struct In; 717f92157deSopenharmony_ci struct Out { 718f92157deSopenharmony_ci int x; 719f92157deSopenharmony_ci 720f92157deSopenharmony_ci explicit Out(const int val) : x(val) {} 721f92157deSopenharmony_ci explicit Out(const In&) : x(0) {} 722f92157deSopenharmony_ci }; 723f92157deSopenharmony_ci 724f92157deSopenharmony_ci struct In { 725f92157deSopenharmony_ci operator Out() const { return Out{19}; } // NOLINT 726f92157deSopenharmony_ci }; 727f92157deSopenharmony_ci 728f92157deSopenharmony_ci // Assumption check: the C++ language rules are such that a function that 729f92157deSopenharmony_ci // returns Out which uses In a return statement will use the implicit 730f92157deSopenharmony_ci // conversion path rather than the explicit constructor. 731f92157deSopenharmony_ci EXPECT_THAT([]() -> Out { return In(); }(), Field(&Out::x, 19)); 732f92157deSopenharmony_ci 733f92157deSopenharmony_ci // Return should work the same way: if the mock function's return type is Out 734f92157deSopenharmony_ci // and we feed Return an In value, then the Out should be created through the 735f92157deSopenharmony_ci // implicit conversion path rather than the explicit constructor. 736f92157deSopenharmony_ci MockFunction<Out()> mock; 737f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(Return(In())); 738f92157deSopenharmony_ci EXPECT_THAT(mock.AsStdFunction()(), Field(&Out::x, 19)); 739f92157deSopenharmony_ci} 740f92157deSopenharmony_ci 741f92157deSopenharmony_ci// It should be possible to use Return(R) with a mock function result type U 742f92157deSopenharmony_ci// that is convertible from const R& but *not* R (such as 743f92157deSopenharmony_ci// std::reference_wrapper). This should work for both WillOnce and 744f92157deSopenharmony_ci// WillRepeatedly. 745f92157deSopenharmony_ciTEST(ReturnTest, ConversionRequiresConstLvalueReference) { 746f92157deSopenharmony_ci using R = int; 747f92157deSopenharmony_ci using U = std::reference_wrapper<const int>; 748f92157deSopenharmony_ci 749f92157deSopenharmony_ci static_assert(std::is_convertible<const R&, U>::value, ""); 750f92157deSopenharmony_ci static_assert(!std::is_convertible<R, U>::value, ""); 751f92157deSopenharmony_ci 752f92157deSopenharmony_ci MockFunction<U()> mock; 753f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(Return(17)).WillRepeatedly(Return(19)); 754f92157deSopenharmony_ci 755f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 756f92157deSopenharmony_ci EXPECT_EQ(19, mock.AsStdFunction()()); 757f92157deSopenharmony_ci} 758f92157deSopenharmony_ci 759f92157deSopenharmony_ci// Return(x) should not be usable with a mock function result type that's 760f92157deSopenharmony_ci// implicitly convertible from decltype(x) but requires a non-const lvalue 761f92157deSopenharmony_ci// reference to the input. It doesn't make sense for the conversion operator to 762f92157deSopenharmony_ci// modify the input. 763f92157deSopenharmony_ciTEST(ReturnTest, ConversionRequiresMutableLvalueReference) { 764f92157deSopenharmony_ci // Set up a type that is implicitly convertible from std::string&, but not 765f92157deSopenharmony_ci // std::string&& or `const std::string&`. 766f92157deSopenharmony_ci // 767f92157deSopenharmony_ci // Avoid asserting about conversion from std::string on MSVC, which seems to 768f92157deSopenharmony_ci // implement std::is_convertible incorrectly in this case. 769f92157deSopenharmony_ci struct S { 770f92157deSopenharmony_ci S(std::string&) {} // NOLINT 771f92157deSopenharmony_ci }; 772f92157deSopenharmony_ci 773f92157deSopenharmony_ci static_assert(std::is_convertible<std::string&, S>::value, ""); 774f92157deSopenharmony_ci#ifndef _MSC_VER 775f92157deSopenharmony_ci static_assert(!std::is_convertible<std::string&&, S>::value, ""); 776f92157deSopenharmony_ci#endif 777f92157deSopenharmony_ci static_assert(!std::is_convertible<const std::string&, S>::value, ""); 778f92157deSopenharmony_ci 779f92157deSopenharmony_ci // It shouldn't be possible to use the result of Return(std::string) in a 780f92157deSopenharmony_ci // context where an S is needed. 781f92157deSopenharmony_ci // 782f92157deSopenharmony_ci // Here too we disable the assertion for MSVC, since its incorrect 783f92157deSopenharmony_ci // implementation of is_convertible causes our SFINAE to be wrong. 784f92157deSopenharmony_ci using RA = decltype(Return(std::string())); 785f92157deSopenharmony_ci 786f92157deSopenharmony_ci static_assert(!std::is_convertible<RA, Action<S()>>::value, ""); 787f92157deSopenharmony_ci#ifndef _MSC_VER 788f92157deSopenharmony_ci static_assert(!std::is_convertible<RA, OnceAction<S()>>::value, ""); 789f92157deSopenharmony_ci#endif 790f92157deSopenharmony_ci} 791f92157deSopenharmony_ci 792f92157deSopenharmony_ciTEST(ReturnTest, MoveOnlyResultType) { 793f92157deSopenharmony_ci // Return should support move-only result types when used with WillOnce. 794f92157deSopenharmony_ci { 795f92157deSopenharmony_ci MockFunction<std::unique_ptr<int>()> mock; 796f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 797f92157deSopenharmony_ci // NOLINTNEXTLINE 798f92157deSopenharmony_ci .WillOnce(Return(std::unique_ptr<int>(new int(17)))); 799f92157deSopenharmony_ci 800f92157deSopenharmony_ci EXPECT_THAT(mock.AsStdFunction()(), Pointee(17)); 801f92157deSopenharmony_ci } 802f92157deSopenharmony_ci 803f92157deSopenharmony_ci // The result of Return should not be convertible to Action (so it can't be 804f92157deSopenharmony_ci // used with WillRepeatedly). 805f92157deSopenharmony_ci static_assert(!std::is_convertible<decltype(Return(std::unique_ptr<int>())), 806f92157deSopenharmony_ci Action<std::unique_ptr<int>()>>::value, 807f92157deSopenharmony_ci ""); 808f92157deSopenharmony_ci} 809f92157deSopenharmony_ci 810f92157deSopenharmony_ci// Tests that Return(v) is covariant. 811f92157deSopenharmony_ci 812f92157deSopenharmony_cistruct Base { 813f92157deSopenharmony_ci bool operator==(const Base&) { return true; } 814f92157deSopenharmony_ci}; 815f92157deSopenharmony_ci 816f92157deSopenharmony_cistruct Derived : public Base { 817f92157deSopenharmony_ci bool operator==(const Derived&) { return true; } 818f92157deSopenharmony_ci}; 819f92157deSopenharmony_ci 820f92157deSopenharmony_ciTEST(ReturnTest, IsCovariant) { 821f92157deSopenharmony_ci Base base; 822f92157deSopenharmony_ci Derived derived; 823f92157deSopenharmony_ci Action<Base*()> ret = Return(&base); 824f92157deSopenharmony_ci EXPECT_EQ(&base, ret.Perform(std::make_tuple())); 825f92157deSopenharmony_ci 826f92157deSopenharmony_ci ret = Return(&derived); 827f92157deSopenharmony_ci EXPECT_EQ(&derived, ret.Perform(std::make_tuple())); 828f92157deSopenharmony_ci} 829f92157deSopenharmony_ci 830f92157deSopenharmony_ci// Tests that the type of the value passed into Return is converted into T 831f92157deSopenharmony_ci// when the action is cast to Action<T(...)> rather than when the action is 832f92157deSopenharmony_ci// performed. See comments on testing::internal::ReturnAction in 833f92157deSopenharmony_ci// gmock-actions.h for more information. 834f92157deSopenharmony_ciclass FromType { 835f92157deSopenharmony_ci public: 836f92157deSopenharmony_ci explicit FromType(bool* is_converted) : converted_(is_converted) {} 837f92157deSopenharmony_ci bool* converted() const { return converted_; } 838f92157deSopenharmony_ci 839f92157deSopenharmony_ci private: 840f92157deSopenharmony_ci bool* const converted_; 841f92157deSopenharmony_ci}; 842f92157deSopenharmony_ci 843f92157deSopenharmony_ciclass ToType { 844f92157deSopenharmony_ci public: 845f92157deSopenharmony_ci // Must allow implicit conversion due to use in ImplicitCast_<T>. 846f92157deSopenharmony_ci ToType(const FromType& x) { *x.converted() = true; } // NOLINT 847f92157deSopenharmony_ci}; 848f92157deSopenharmony_ci 849f92157deSopenharmony_ciTEST(ReturnTest, ConvertsArgumentWhenConverted) { 850f92157deSopenharmony_ci bool converted = false; 851f92157deSopenharmony_ci FromType x(&converted); 852f92157deSopenharmony_ci Action<ToType()> action(Return(x)); 853f92157deSopenharmony_ci EXPECT_TRUE(converted) << "Return must convert its argument in its own " 854f92157deSopenharmony_ci << "conversion operator."; 855f92157deSopenharmony_ci converted = false; 856f92157deSopenharmony_ci action.Perform(std::tuple<>()); 857f92157deSopenharmony_ci EXPECT_FALSE(converted) << "Action must NOT convert its argument " 858f92157deSopenharmony_ci << "when performed."; 859f92157deSopenharmony_ci} 860f92157deSopenharmony_ci 861f92157deSopenharmony_ci// Tests that ReturnNull() returns NULL in a pointer-returning function. 862f92157deSopenharmony_ciTEST(ReturnNullTest, WorksInPointerReturningFunction) { 863f92157deSopenharmony_ci const Action<int*()> a1 = ReturnNull(); 864f92157deSopenharmony_ci EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr); 865f92157deSopenharmony_ci 866f92157deSopenharmony_ci const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT 867f92157deSopenharmony_ci EXPECT_TRUE(a2.Perform(std::make_tuple(true)) == nullptr); 868f92157deSopenharmony_ci} 869f92157deSopenharmony_ci 870f92157deSopenharmony_ci// Tests that ReturnNull() returns NULL for shared_ptr and unique_ptr returning 871f92157deSopenharmony_ci// functions. 872f92157deSopenharmony_ciTEST(ReturnNullTest, WorksInSmartPointerReturningFunction) { 873f92157deSopenharmony_ci const Action<std::unique_ptr<const int>()> a1 = ReturnNull(); 874f92157deSopenharmony_ci EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr); 875f92157deSopenharmony_ci 876f92157deSopenharmony_ci const Action<std::shared_ptr<int>(std::string)> a2 = ReturnNull(); 877f92157deSopenharmony_ci EXPECT_TRUE(a2.Perform(std::make_tuple("foo")) == nullptr); 878f92157deSopenharmony_ci} 879f92157deSopenharmony_ci 880f92157deSopenharmony_ci// Tests that ReturnRef(v) works for reference types. 881f92157deSopenharmony_ciTEST(ReturnRefTest, WorksForReference) { 882f92157deSopenharmony_ci const int n = 0; 883f92157deSopenharmony_ci const Action<const int&(bool)> ret = ReturnRef(n); // NOLINT 884f92157deSopenharmony_ci 885f92157deSopenharmony_ci EXPECT_EQ(&n, &ret.Perform(std::make_tuple(true))); 886f92157deSopenharmony_ci} 887f92157deSopenharmony_ci 888f92157deSopenharmony_ci// Tests that ReturnRef(v) is covariant. 889f92157deSopenharmony_ciTEST(ReturnRefTest, IsCovariant) { 890f92157deSopenharmony_ci Base base; 891f92157deSopenharmony_ci Derived derived; 892f92157deSopenharmony_ci Action<Base&()> a = ReturnRef(base); 893f92157deSopenharmony_ci EXPECT_EQ(&base, &a.Perform(std::make_tuple())); 894f92157deSopenharmony_ci 895f92157deSopenharmony_ci a = ReturnRef(derived); 896f92157deSopenharmony_ci EXPECT_EQ(&derived, &a.Perform(std::make_tuple())); 897f92157deSopenharmony_ci} 898f92157deSopenharmony_ci 899f92157deSopenharmony_citemplate <typename T, typename = decltype(ReturnRef(std::declval<T&&>()))> 900f92157deSopenharmony_cibool CanCallReturnRef(T&&) { 901f92157deSopenharmony_ci return true; 902f92157deSopenharmony_ci} 903f92157deSopenharmony_cibool CanCallReturnRef(Unused) { return false; } 904f92157deSopenharmony_ci 905f92157deSopenharmony_ci// Tests that ReturnRef(v) is working with non-temporaries (T&) 906f92157deSopenharmony_ciTEST(ReturnRefTest, WorksForNonTemporary) { 907f92157deSopenharmony_ci int scalar_value = 123; 908f92157deSopenharmony_ci EXPECT_TRUE(CanCallReturnRef(scalar_value)); 909f92157deSopenharmony_ci 910f92157deSopenharmony_ci std::string non_scalar_value("ABC"); 911f92157deSopenharmony_ci EXPECT_TRUE(CanCallReturnRef(non_scalar_value)); 912f92157deSopenharmony_ci 913f92157deSopenharmony_ci const int const_scalar_value{321}; 914f92157deSopenharmony_ci EXPECT_TRUE(CanCallReturnRef(const_scalar_value)); 915f92157deSopenharmony_ci 916f92157deSopenharmony_ci const std::string const_non_scalar_value("CBA"); 917f92157deSopenharmony_ci EXPECT_TRUE(CanCallReturnRef(const_non_scalar_value)); 918f92157deSopenharmony_ci} 919f92157deSopenharmony_ci 920f92157deSopenharmony_ci// Tests that ReturnRef(v) is not working with temporaries (T&&) 921f92157deSopenharmony_ciTEST(ReturnRefTest, DoesNotWorkForTemporary) { 922f92157deSopenharmony_ci auto scalar_value = []() -> int { return 123; }; 923f92157deSopenharmony_ci EXPECT_FALSE(CanCallReturnRef(scalar_value())); 924f92157deSopenharmony_ci 925f92157deSopenharmony_ci auto non_scalar_value = []() -> std::string { return "ABC"; }; 926f92157deSopenharmony_ci EXPECT_FALSE(CanCallReturnRef(non_scalar_value())); 927f92157deSopenharmony_ci 928f92157deSopenharmony_ci // cannot use here callable returning "const scalar type", 929f92157deSopenharmony_ci // because such const for scalar return type is ignored 930f92157deSopenharmony_ci EXPECT_FALSE(CanCallReturnRef(static_cast<const int>(321))); 931f92157deSopenharmony_ci 932f92157deSopenharmony_ci auto const_non_scalar_value = []() -> const std::string { return "CBA"; }; 933f92157deSopenharmony_ci EXPECT_FALSE(CanCallReturnRef(const_non_scalar_value())); 934f92157deSopenharmony_ci} 935f92157deSopenharmony_ci 936f92157deSopenharmony_ci// Tests that ReturnRefOfCopy(v) works for reference types. 937f92157deSopenharmony_ciTEST(ReturnRefOfCopyTest, WorksForReference) { 938f92157deSopenharmony_ci int n = 42; 939f92157deSopenharmony_ci const Action<const int&()> ret = ReturnRefOfCopy(n); 940f92157deSopenharmony_ci 941f92157deSopenharmony_ci EXPECT_NE(&n, &ret.Perform(std::make_tuple())); 942f92157deSopenharmony_ci EXPECT_EQ(42, ret.Perform(std::make_tuple())); 943f92157deSopenharmony_ci 944f92157deSopenharmony_ci n = 43; 945f92157deSopenharmony_ci EXPECT_NE(&n, &ret.Perform(std::make_tuple())); 946f92157deSopenharmony_ci EXPECT_EQ(42, ret.Perform(std::make_tuple())); 947f92157deSopenharmony_ci} 948f92157deSopenharmony_ci 949f92157deSopenharmony_ci// Tests that ReturnRefOfCopy(v) is covariant. 950f92157deSopenharmony_ciTEST(ReturnRefOfCopyTest, IsCovariant) { 951f92157deSopenharmony_ci Base base; 952f92157deSopenharmony_ci Derived derived; 953f92157deSopenharmony_ci Action<Base&()> a = ReturnRefOfCopy(base); 954f92157deSopenharmony_ci EXPECT_NE(&base, &a.Perform(std::make_tuple())); 955f92157deSopenharmony_ci 956f92157deSopenharmony_ci a = ReturnRefOfCopy(derived); 957f92157deSopenharmony_ci EXPECT_NE(&derived, &a.Perform(std::make_tuple())); 958f92157deSopenharmony_ci} 959f92157deSopenharmony_ci 960f92157deSopenharmony_ci// Tests that ReturnRoundRobin(v) works with initializer lists 961f92157deSopenharmony_ciTEST(ReturnRoundRobinTest, WorksForInitList) { 962f92157deSopenharmony_ci Action<int()> ret = ReturnRoundRobin({1, 2, 3}); 963f92157deSopenharmony_ci 964f92157deSopenharmony_ci EXPECT_EQ(1, ret.Perform(std::make_tuple())); 965f92157deSopenharmony_ci EXPECT_EQ(2, ret.Perform(std::make_tuple())); 966f92157deSopenharmony_ci EXPECT_EQ(3, ret.Perform(std::make_tuple())); 967f92157deSopenharmony_ci EXPECT_EQ(1, ret.Perform(std::make_tuple())); 968f92157deSopenharmony_ci EXPECT_EQ(2, ret.Perform(std::make_tuple())); 969f92157deSopenharmony_ci EXPECT_EQ(3, ret.Perform(std::make_tuple())); 970f92157deSopenharmony_ci} 971f92157deSopenharmony_ci 972f92157deSopenharmony_ci// Tests that ReturnRoundRobin(v) works with vectors 973f92157deSopenharmony_ciTEST(ReturnRoundRobinTest, WorksForVector) { 974f92157deSopenharmony_ci std::vector<double> v = {4.4, 5.5, 6.6}; 975f92157deSopenharmony_ci Action<double()> ret = ReturnRoundRobin(v); 976f92157deSopenharmony_ci 977f92157deSopenharmony_ci EXPECT_EQ(4.4, ret.Perform(std::make_tuple())); 978f92157deSopenharmony_ci EXPECT_EQ(5.5, ret.Perform(std::make_tuple())); 979f92157deSopenharmony_ci EXPECT_EQ(6.6, ret.Perform(std::make_tuple())); 980f92157deSopenharmony_ci EXPECT_EQ(4.4, ret.Perform(std::make_tuple())); 981f92157deSopenharmony_ci EXPECT_EQ(5.5, ret.Perform(std::make_tuple())); 982f92157deSopenharmony_ci EXPECT_EQ(6.6, ret.Perform(std::make_tuple())); 983f92157deSopenharmony_ci} 984f92157deSopenharmony_ci 985f92157deSopenharmony_ci// Tests that DoDefault() does the default action for the mock method. 986f92157deSopenharmony_ci 987f92157deSopenharmony_ciclass MockClass { 988f92157deSopenharmony_ci public: 989f92157deSopenharmony_ci MockClass() {} 990f92157deSopenharmony_ci 991f92157deSopenharmony_ci MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT 992f92157deSopenharmony_ci MOCK_METHOD0(Foo, MyNonDefaultConstructible()); 993f92157deSopenharmony_ci MOCK_METHOD0(MakeUnique, std::unique_ptr<int>()); 994f92157deSopenharmony_ci MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>()); 995f92157deSopenharmony_ci MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>()); 996f92157deSopenharmony_ci MOCK_METHOD1(TakeUnique, int(std::unique_ptr<int>)); 997f92157deSopenharmony_ci MOCK_METHOD2(TakeUnique, 998f92157deSopenharmony_ci int(const std::unique_ptr<int>&, std::unique_ptr<int>)); 999f92157deSopenharmony_ci 1000f92157deSopenharmony_ci private: 1001f92157deSopenharmony_ci MockClass(const MockClass&) = delete; 1002f92157deSopenharmony_ci MockClass& operator=(const MockClass&) = delete; 1003f92157deSopenharmony_ci}; 1004f92157deSopenharmony_ci 1005f92157deSopenharmony_ci// Tests that DoDefault() returns the built-in default value for the 1006f92157deSopenharmony_ci// return type by default. 1007f92157deSopenharmony_ciTEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) { 1008f92157deSopenharmony_ci MockClass mock; 1009f92157deSopenharmony_ci EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault()); 1010f92157deSopenharmony_ci EXPECT_EQ(0, mock.IntFunc(true)); 1011f92157deSopenharmony_ci} 1012f92157deSopenharmony_ci 1013f92157deSopenharmony_ci// Tests that DoDefault() throws (when exceptions are enabled) or aborts 1014f92157deSopenharmony_ci// the process when there is no built-in default value for the return type. 1015f92157deSopenharmony_ciTEST(DoDefaultDeathTest, DiesForUnknowType) { 1016f92157deSopenharmony_ci MockClass mock; 1017f92157deSopenharmony_ci EXPECT_CALL(mock, Foo()).WillRepeatedly(DoDefault()); 1018f92157deSopenharmony_ci#if GTEST_HAS_EXCEPTIONS 1019f92157deSopenharmony_ci EXPECT_ANY_THROW(mock.Foo()); 1020f92157deSopenharmony_ci#else 1021f92157deSopenharmony_ci EXPECT_DEATH_IF_SUPPORTED({ mock.Foo(); }, ""); 1022f92157deSopenharmony_ci#endif 1023f92157deSopenharmony_ci} 1024f92157deSopenharmony_ci 1025f92157deSopenharmony_ci// Tests that using DoDefault() inside a composite action leads to a 1026f92157deSopenharmony_ci// run-time error. 1027f92157deSopenharmony_ci 1028f92157deSopenharmony_civoid VoidFunc(bool /* flag */) {} 1029f92157deSopenharmony_ci 1030f92157deSopenharmony_ciTEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) { 1031f92157deSopenharmony_ci MockClass mock; 1032f92157deSopenharmony_ci EXPECT_CALL(mock, IntFunc(_)) 1033f92157deSopenharmony_ci .WillRepeatedly(DoAll(Invoke(VoidFunc), DoDefault())); 1034f92157deSopenharmony_ci 1035f92157deSopenharmony_ci // Ideally we should verify the error message as well. Sadly, 1036f92157deSopenharmony_ci // EXPECT_DEATH() can only capture stderr, while Google Mock's 1037f92157deSopenharmony_ci // errors are printed on stdout. Therefore we have to settle for 1038f92157deSopenharmony_ci // not verifying the message. 1039f92157deSopenharmony_ci EXPECT_DEATH_IF_SUPPORTED({ mock.IntFunc(true); }, ""); 1040f92157deSopenharmony_ci} 1041f92157deSopenharmony_ci 1042f92157deSopenharmony_ci// Tests that DoDefault() returns the default value set by 1043f92157deSopenharmony_ci// DefaultValue<T>::Set() when it's not overridden by an ON_CALL(). 1044f92157deSopenharmony_ciTEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { 1045f92157deSopenharmony_ci DefaultValue<int>::Set(1); 1046f92157deSopenharmony_ci MockClass mock; 1047f92157deSopenharmony_ci EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault()); 1048f92157deSopenharmony_ci EXPECT_EQ(1, mock.IntFunc(false)); 1049f92157deSopenharmony_ci DefaultValue<int>::Clear(); 1050f92157deSopenharmony_ci} 1051f92157deSopenharmony_ci 1052f92157deSopenharmony_ci// Tests that DoDefault() does the action specified by ON_CALL(). 1053f92157deSopenharmony_ciTEST(DoDefaultTest, DoesWhatOnCallSpecifies) { 1054f92157deSopenharmony_ci MockClass mock; 1055f92157deSopenharmony_ci ON_CALL(mock, IntFunc(_)).WillByDefault(Return(2)); 1056f92157deSopenharmony_ci EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault()); 1057f92157deSopenharmony_ci EXPECT_EQ(2, mock.IntFunc(false)); 1058f92157deSopenharmony_ci} 1059f92157deSopenharmony_ci 1060f92157deSopenharmony_ci// Tests that using DoDefault() in ON_CALL() leads to a run-time failure. 1061f92157deSopenharmony_ciTEST(DoDefaultTest, CannotBeUsedInOnCall) { 1062f92157deSopenharmony_ci MockClass mock; 1063f92157deSopenharmony_ci EXPECT_NONFATAL_FAILURE( 1064f92157deSopenharmony_ci { // NOLINT 1065f92157deSopenharmony_ci ON_CALL(mock, IntFunc(_)).WillByDefault(DoDefault()); 1066f92157deSopenharmony_ci }, 1067f92157deSopenharmony_ci "DoDefault() cannot be used in ON_CALL()"); 1068f92157deSopenharmony_ci} 1069f92157deSopenharmony_ci 1070f92157deSopenharmony_ci// Tests that SetArgPointee<N>(v) sets the variable pointed to by 1071f92157deSopenharmony_ci// the N-th (0-based) argument to v. 1072f92157deSopenharmony_ciTEST(SetArgPointeeTest, SetsTheNthPointee) { 1073f92157deSopenharmony_ci typedef void MyFunction(bool, int*, char*); 1074f92157deSopenharmony_ci Action<MyFunction> a = SetArgPointee<1>(2); 1075f92157deSopenharmony_ci 1076f92157deSopenharmony_ci int n = 0; 1077f92157deSopenharmony_ci char ch = '\0'; 1078f92157deSopenharmony_ci a.Perform(std::make_tuple(true, &n, &ch)); 1079f92157deSopenharmony_ci EXPECT_EQ(2, n); 1080f92157deSopenharmony_ci EXPECT_EQ('\0', ch); 1081f92157deSopenharmony_ci 1082f92157deSopenharmony_ci a = SetArgPointee<2>('a'); 1083f92157deSopenharmony_ci n = 0; 1084f92157deSopenharmony_ci ch = '\0'; 1085f92157deSopenharmony_ci a.Perform(std::make_tuple(true, &n, &ch)); 1086f92157deSopenharmony_ci EXPECT_EQ(0, n); 1087f92157deSopenharmony_ci EXPECT_EQ('a', ch); 1088f92157deSopenharmony_ci} 1089f92157deSopenharmony_ci 1090f92157deSopenharmony_ci// Tests that SetArgPointee<N>() accepts a string literal. 1091f92157deSopenharmony_ciTEST(SetArgPointeeTest, AcceptsStringLiteral) { 1092f92157deSopenharmony_ci typedef void MyFunction(std::string*, const char**); 1093f92157deSopenharmony_ci Action<MyFunction> a = SetArgPointee<0>("hi"); 1094f92157deSopenharmony_ci std::string str; 1095f92157deSopenharmony_ci const char* ptr = nullptr; 1096f92157deSopenharmony_ci a.Perform(std::make_tuple(&str, &ptr)); 1097f92157deSopenharmony_ci EXPECT_EQ("hi", str); 1098f92157deSopenharmony_ci EXPECT_TRUE(ptr == nullptr); 1099f92157deSopenharmony_ci 1100f92157deSopenharmony_ci a = SetArgPointee<1>("world"); 1101f92157deSopenharmony_ci str = ""; 1102f92157deSopenharmony_ci a.Perform(std::make_tuple(&str, &ptr)); 1103f92157deSopenharmony_ci EXPECT_EQ("", str); 1104f92157deSopenharmony_ci EXPECT_STREQ("world", ptr); 1105f92157deSopenharmony_ci} 1106f92157deSopenharmony_ci 1107f92157deSopenharmony_ciTEST(SetArgPointeeTest, AcceptsWideStringLiteral) { 1108f92157deSopenharmony_ci typedef void MyFunction(const wchar_t**); 1109f92157deSopenharmony_ci Action<MyFunction> a = SetArgPointee<0>(L"world"); 1110f92157deSopenharmony_ci const wchar_t* ptr = nullptr; 1111f92157deSopenharmony_ci a.Perform(std::make_tuple(&ptr)); 1112f92157deSopenharmony_ci EXPECT_STREQ(L"world", ptr); 1113f92157deSopenharmony_ci 1114f92157deSopenharmony_ci#if GTEST_HAS_STD_WSTRING 1115f92157deSopenharmony_ci 1116f92157deSopenharmony_ci typedef void MyStringFunction(std::wstring*); 1117f92157deSopenharmony_ci Action<MyStringFunction> a2 = SetArgPointee<0>(L"world"); 1118f92157deSopenharmony_ci std::wstring str = L""; 1119f92157deSopenharmony_ci a2.Perform(std::make_tuple(&str)); 1120f92157deSopenharmony_ci EXPECT_EQ(L"world", str); 1121f92157deSopenharmony_ci 1122f92157deSopenharmony_ci#endif 1123f92157deSopenharmony_ci} 1124f92157deSopenharmony_ci 1125f92157deSopenharmony_ci// Tests that SetArgPointee<N>() accepts a char pointer. 1126f92157deSopenharmony_ciTEST(SetArgPointeeTest, AcceptsCharPointer) { 1127f92157deSopenharmony_ci typedef void MyFunction(bool, std::string*, const char**); 1128f92157deSopenharmony_ci const char* const hi = "hi"; 1129f92157deSopenharmony_ci Action<MyFunction> a = SetArgPointee<1>(hi); 1130f92157deSopenharmony_ci std::string str; 1131f92157deSopenharmony_ci const char* ptr = nullptr; 1132f92157deSopenharmony_ci a.Perform(std::make_tuple(true, &str, &ptr)); 1133f92157deSopenharmony_ci EXPECT_EQ("hi", str); 1134f92157deSopenharmony_ci EXPECT_TRUE(ptr == nullptr); 1135f92157deSopenharmony_ci 1136f92157deSopenharmony_ci char world_array[] = "world"; 1137f92157deSopenharmony_ci char* const world = world_array; 1138f92157deSopenharmony_ci a = SetArgPointee<2>(world); 1139f92157deSopenharmony_ci str = ""; 1140f92157deSopenharmony_ci a.Perform(std::make_tuple(true, &str, &ptr)); 1141f92157deSopenharmony_ci EXPECT_EQ("", str); 1142f92157deSopenharmony_ci EXPECT_EQ(world, ptr); 1143f92157deSopenharmony_ci} 1144f92157deSopenharmony_ci 1145f92157deSopenharmony_ciTEST(SetArgPointeeTest, AcceptsWideCharPointer) { 1146f92157deSopenharmony_ci typedef void MyFunction(bool, const wchar_t**); 1147f92157deSopenharmony_ci const wchar_t* const hi = L"hi"; 1148f92157deSopenharmony_ci Action<MyFunction> a = SetArgPointee<1>(hi); 1149f92157deSopenharmony_ci const wchar_t* ptr = nullptr; 1150f92157deSopenharmony_ci a.Perform(std::make_tuple(true, &ptr)); 1151f92157deSopenharmony_ci EXPECT_EQ(hi, ptr); 1152f92157deSopenharmony_ci 1153f92157deSopenharmony_ci#if GTEST_HAS_STD_WSTRING 1154f92157deSopenharmony_ci 1155f92157deSopenharmony_ci typedef void MyStringFunction(bool, std::wstring*); 1156f92157deSopenharmony_ci wchar_t world_array[] = L"world"; 1157f92157deSopenharmony_ci wchar_t* const world = world_array; 1158f92157deSopenharmony_ci Action<MyStringFunction> a2 = SetArgPointee<1>(world); 1159f92157deSopenharmony_ci std::wstring str; 1160f92157deSopenharmony_ci a2.Perform(std::make_tuple(true, &str)); 1161f92157deSopenharmony_ci EXPECT_EQ(world_array, str); 1162f92157deSopenharmony_ci#endif 1163f92157deSopenharmony_ci} 1164f92157deSopenharmony_ci 1165f92157deSopenharmony_ci// Tests that SetArgumentPointee<N>(v) sets the variable pointed to by 1166f92157deSopenharmony_ci// the N-th (0-based) argument to v. 1167f92157deSopenharmony_ciTEST(SetArgumentPointeeTest, SetsTheNthPointee) { 1168f92157deSopenharmony_ci typedef void MyFunction(bool, int*, char*); 1169f92157deSopenharmony_ci Action<MyFunction> a = SetArgumentPointee<1>(2); 1170f92157deSopenharmony_ci 1171f92157deSopenharmony_ci int n = 0; 1172f92157deSopenharmony_ci char ch = '\0'; 1173f92157deSopenharmony_ci a.Perform(std::make_tuple(true, &n, &ch)); 1174f92157deSopenharmony_ci EXPECT_EQ(2, n); 1175f92157deSopenharmony_ci EXPECT_EQ('\0', ch); 1176f92157deSopenharmony_ci 1177f92157deSopenharmony_ci a = SetArgumentPointee<2>('a'); 1178f92157deSopenharmony_ci n = 0; 1179f92157deSopenharmony_ci ch = '\0'; 1180f92157deSopenharmony_ci a.Perform(std::make_tuple(true, &n, &ch)); 1181f92157deSopenharmony_ci EXPECT_EQ(0, n); 1182f92157deSopenharmony_ci EXPECT_EQ('a', ch); 1183f92157deSopenharmony_ci} 1184f92157deSopenharmony_ci 1185f92157deSopenharmony_ci// Sample functions and functors for testing Invoke() and etc. 1186f92157deSopenharmony_ciint Nullary() { return 1; } 1187f92157deSopenharmony_ci 1188f92157deSopenharmony_ciclass NullaryFunctor { 1189f92157deSopenharmony_ci public: 1190f92157deSopenharmony_ci int operator()() { return 2; } 1191f92157deSopenharmony_ci}; 1192f92157deSopenharmony_ci 1193f92157deSopenharmony_cibool g_done = false; 1194f92157deSopenharmony_civoid VoidNullary() { g_done = true; } 1195f92157deSopenharmony_ci 1196f92157deSopenharmony_ciclass VoidNullaryFunctor { 1197f92157deSopenharmony_ci public: 1198f92157deSopenharmony_ci void operator()() { g_done = true; } 1199f92157deSopenharmony_ci}; 1200f92157deSopenharmony_ci 1201f92157deSopenharmony_cishort Short(short n) { return n; } // NOLINT 1202f92157deSopenharmony_cichar Char(char ch) { return ch; } 1203f92157deSopenharmony_ci 1204f92157deSopenharmony_ciconst char* CharPtr(const char* s) { return s; } 1205f92157deSopenharmony_ci 1206f92157deSopenharmony_cibool Unary(int x) { return x < 0; } 1207f92157deSopenharmony_ci 1208f92157deSopenharmony_ciconst char* Binary(const char* input, short n) { return input + n; } // NOLINT 1209f92157deSopenharmony_ci 1210f92157deSopenharmony_civoid VoidBinary(int, char) { g_done = true; } 1211f92157deSopenharmony_ci 1212f92157deSopenharmony_ciint Ternary(int x, char y, short z) { return x + y + z; } // NOLINT 1213f92157deSopenharmony_ci 1214f92157deSopenharmony_ciint SumOf4(int a, int b, int c, int d) { return a + b + c + d; } 1215f92157deSopenharmony_ci 1216f92157deSopenharmony_ciclass Foo { 1217f92157deSopenharmony_ci public: 1218f92157deSopenharmony_ci Foo() : value_(123) {} 1219f92157deSopenharmony_ci 1220f92157deSopenharmony_ci int Nullary() const { return value_; } 1221f92157deSopenharmony_ci 1222f92157deSopenharmony_ci private: 1223f92157deSopenharmony_ci int value_; 1224f92157deSopenharmony_ci}; 1225f92157deSopenharmony_ci 1226f92157deSopenharmony_ci// Tests InvokeWithoutArgs(function). 1227f92157deSopenharmony_ciTEST(InvokeWithoutArgsTest, Function) { 1228f92157deSopenharmony_ci // As an action that takes one argument. 1229f92157deSopenharmony_ci Action<int(int)> a = InvokeWithoutArgs(Nullary); // NOLINT 1230f92157deSopenharmony_ci EXPECT_EQ(1, a.Perform(std::make_tuple(2))); 1231f92157deSopenharmony_ci 1232f92157deSopenharmony_ci // As an action that takes two arguments. 1233f92157deSopenharmony_ci Action<int(int, double)> a2 = InvokeWithoutArgs(Nullary); // NOLINT 1234f92157deSopenharmony_ci EXPECT_EQ(1, a2.Perform(std::make_tuple(2, 3.5))); 1235f92157deSopenharmony_ci 1236f92157deSopenharmony_ci // As an action that returns void. 1237f92157deSopenharmony_ci Action<void(int)> a3 = InvokeWithoutArgs(VoidNullary); // NOLINT 1238f92157deSopenharmony_ci g_done = false; 1239f92157deSopenharmony_ci a3.Perform(std::make_tuple(1)); 1240f92157deSopenharmony_ci EXPECT_TRUE(g_done); 1241f92157deSopenharmony_ci} 1242f92157deSopenharmony_ci 1243f92157deSopenharmony_ci// Tests InvokeWithoutArgs(functor). 1244f92157deSopenharmony_ciTEST(InvokeWithoutArgsTest, Functor) { 1245f92157deSopenharmony_ci // As an action that takes no argument. 1246f92157deSopenharmony_ci Action<int()> a = InvokeWithoutArgs(NullaryFunctor()); // NOLINT 1247f92157deSopenharmony_ci EXPECT_EQ(2, a.Perform(std::make_tuple())); 1248f92157deSopenharmony_ci 1249f92157deSopenharmony_ci // As an action that takes three arguments. 1250f92157deSopenharmony_ci Action<int(int, double, char)> a2 = // NOLINT 1251f92157deSopenharmony_ci InvokeWithoutArgs(NullaryFunctor()); 1252f92157deSopenharmony_ci EXPECT_EQ(2, a2.Perform(std::make_tuple(3, 3.5, 'a'))); 1253f92157deSopenharmony_ci 1254f92157deSopenharmony_ci // As an action that returns void. 1255f92157deSopenharmony_ci Action<void()> a3 = InvokeWithoutArgs(VoidNullaryFunctor()); 1256f92157deSopenharmony_ci g_done = false; 1257f92157deSopenharmony_ci a3.Perform(std::make_tuple()); 1258f92157deSopenharmony_ci EXPECT_TRUE(g_done); 1259f92157deSopenharmony_ci} 1260f92157deSopenharmony_ci 1261f92157deSopenharmony_ci// Tests InvokeWithoutArgs(obj_ptr, method). 1262f92157deSopenharmony_ciTEST(InvokeWithoutArgsTest, Method) { 1263f92157deSopenharmony_ci Foo foo; 1264f92157deSopenharmony_ci Action<int(bool, char)> a = // NOLINT 1265f92157deSopenharmony_ci InvokeWithoutArgs(&foo, &Foo::Nullary); 1266f92157deSopenharmony_ci EXPECT_EQ(123, a.Perform(std::make_tuple(true, 'a'))); 1267f92157deSopenharmony_ci} 1268f92157deSopenharmony_ci 1269f92157deSopenharmony_ci// Tests using IgnoreResult() on a polymorphic action. 1270f92157deSopenharmony_ciTEST(IgnoreResultTest, PolymorphicAction) { 1271f92157deSopenharmony_ci Action<void(int)> a = IgnoreResult(Return(5)); // NOLINT 1272f92157deSopenharmony_ci a.Perform(std::make_tuple(1)); 1273f92157deSopenharmony_ci} 1274f92157deSopenharmony_ci 1275f92157deSopenharmony_ci// Tests using IgnoreResult() on a monomorphic action. 1276f92157deSopenharmony_ci 1277f92157deSopenharmony_ciint ReturnOne() { 1278f92157deSopenharmony_ci g_done = true; 1279f92157deSopenharmony_ci return 1; 1280f92157deSopenharmony_ci} 1281f92157deSopenharmony_ci 1282f92157deSopenharmony_ciTEST(IgnoreResultTest, MonomorphicAction) { 1283f92157deSopenharmony_ci g_done = false; 1284f92157deSopenharmony_ci Action<void()> a = IgnoreResult(Invoke(ReturnOne)); 1285f92157deSopenharmony_ci a.Perform(std::make_tuple()); 1286f92157deSopenharmony_ci EXPECT_TRUE(g_done); 1287f92157deSopenharmony_ci} 1288f92157deSopenharmony_ci 1289f92157deSopenharmony_ci// Tests using IgnoreResult() on an action that returns a class type. 1290f92157deSopenharmony_ci 1291f92157deSopenharmony_ciMyNonDefaultConstructible ReturnMyNonDefaultConstructible(double /* x */) { 1292f92157deSopenharmony_ci g_done = true; 1293f92157deSopenharmony_ci return MyNonDefaultConstructible(42); 1294f92157deSopenharmony_ci} 1295f92157deSopenharmony_ci 1296f92157deSopenharmony_ciTEST(IgnoreResultTest, ActionReturningClass) { 1297f92157deSopenharmony_ci g_done = false; 1298f92157deSopenharmony_ci Action<void(int)> a = 1299f92157deSopenharmony_ci IgnoreResult(Invoke(ReturnMyNonDefaultConstructible)); // NOLINT 1300f92157deSopenharmony_ci a.Perform(std::make_tuple(2)); 1301f92157deSopenharmony_ci EXPECT_TRUE(g_done); 1302f92157deSopenharmony_ci} 1303f92157deSopenharmony_ci 1304f92157deSopenharmony_ciTEST(AssignTest, Int) { 1305f92157deSopenharmony_ci int x = 0; 1306f92157deSopenharmony_ci Action<void(int)> a = Assign(&x, 5); 1307f92157deSopenharmony_ci a.Perform(std::make_tuple(0)); 1308f92157deSopenharmony_ci EXPECT_EQ(5, x); 1309f92157deSopenharmony_ci} 1310f92157deSopenharmony_ci 1311f92157deSopenharmony_ciTEST(AssignTest, String) { 1312f92157deSopenharmony_ci ::std::string x; 1313f92157deSopenharmony_ci Action<void(void)> a = Assign(&x, "Hello, world"); 1314f92157deSopenharmony_ci a.Perform(std::make_tuple()); 1315f92157deSopenharmony_ci EXPECT_EQ("Hello, world", x); 1316f92157deSopenharmony_ci} 1317f92157deSopenharmony_ci 1318f92157deSopenharmony_ciTEST(AssignTest, CompatibleTypes) { 1319f92157deSopenharmony_ci double x = 0; 1320f92157deSopenharmony_ci Action<void(int)> a = Assign(&x, 5); 1321f92157deSopenharmony_ci a.Perform(std::make_tuple(0)); 1322f92157deSopenharmony_ci EXPECT_DOUBLE_EQ(5, x); 1323f92157deSopenharmony_ci} 1324f92157deSopenharmony_ci 1325f92157deSopenharmony_ci// DoAll should support &&-qualified actions when used with WillOnce. 1326f92157deSopenharmony_ciTEST(DoAll, SupportsRefQualifiedActions) { 1327f92157deSopenharmony_ci struct InitialAction { 1328f92157deSopenharmony_ci void operator()(const int arg) && { EXPECT_EQ(17, arg); } 1329f92157deSopenharmony_ci }; 1330f92157deSopenharmony_ci 1331f92157deSopenharmony_ci struct FinalAction { 1332f92157deSopenharmony_ci int operator()() && { return 19; } 1333f92157deSopenharmony_ci }; 1334f92157deSopenharmony_ci 1335f92157deSopenharmony_ci MockFunction<int(int)> mock; 1336f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(DoAll(InitialAction{}, FinalAction{})); 1337f92157deSopenharmony_ci EXPECT_EQ(19, mock.AsStdFunction()(17)); 1338f92157deSopenharmony_ci} 1339f92157deSopenharmony_ci 1340f92157deSopenharmony_ci// DoAll should never provide rvalue references to the initial actions. If the 1341f92157deSopenharmony_ci// mock action itself accepts an rvalue reference or a non-scalar object by 1342f92157deSopenharmony_ci// value then the final action should receive an rvalue reference, but initial 1343f92157deSopenharmony_ci// actions should receive only lvalue references. 1344f92157deSopenharmony_ciTEST(DoAll, ProvidesLvalueReferencesToInitialActions) { 1345f92157deSopenharmony_ci struct Obj {}; 1346f92157deSopenharmony_ci 1347f92157deSopenharmony_ci // Mock action accepts by value: the initial action should be fed a const 1348f92157deSopenharmony_ci // lvalue reference, and the final action an rvalue reference. 1349f92157deSopenharmony_ci { 1350f92157deSopenharmony_ci struct InitialAction { 1351f92157deSopenharmony_ci void operator()(Obj&) const { FAIL() << "Unexpected call"; } 1352f92157deSopenharmony_ci void operator()(const Obj&) const {} 1353f92157deSopenharmony_ci void operator()(Obj&&) const { FAIL() << "Unexpected call"; } 1354f92157deSopenharmony_ci void operator()(const Obj&&) const { FAIL() << "Unexpected call"; } 1355f92157deSopenharmony_ci }; 1356f92157deSopenharmony_ci 1357f92157deSopenharmony_ci MockFunction<void(Obj)> mock; 1358f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1359f92157deSopenharmony_ci .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})) 1360f92157deSopenharmony_ci .WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})); 1361f92157deSopenharmony_ci 1362f92157deSopenharmony_ci mock.AsStdFunction()(Obj{}); 1363f92157deSopenharmony_ci mock.AsStdFunction()(Obj{}); 1364f92157deSopenharmony_ci } 1365f92157deSopenharmony_ci 1366f92157deSopenharmony_ci // Mock action accepts by const lvalue reference: both actions should receive 1367f92157deSopenharmony_ci // a const lvalue reference. 1368f92157deSopenharmony_ci { 1369f92157deSopenharmony_ci struct InitialAction { 1370f92157deSopenharmony_ci void operator()(Obj&) const { FAIL() << "Unexpected call"; } 1371f92157deSopenharmony_ci void operator()(const Obj&) const {} 1372f92157deSopenharmony_ci void operator()(Obj&&) const { FAIL() << "Unexpected call"; } 1373f92157deSopenharmony_ci void operator()(const Obj&&) const { FAIL() << "Unexpected call"; } 1374f92157deSopenharmony_ci }; 1375f92157deSopenharmony_ci 1376f92157deSopenharmony_ci MockFunction<void(const Obj&)> mock; 1377f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1378f92157deSopenharmony_ci .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](const Obj&) {})) 1379f92157deSopenharmony_ci .WillRepeatedly( 1380f92157deSopenharmony_ci DoAll(InitialAction{}, InitialAction{}, [](const Obj&) {})); 1381f92157deSopenharmony_ci 1382f92157deSopenharmony_ci mock.AsStdFunction()(Obj{}); 1383f92157deSopenharmony_ci mock.AsStdFunction()(Obj{}); 1384f92157deSopenharmony_ci } 1385f92157deSopenharmony_ci 1386f92157deSopenharmony_ci // Mock action accepts by non-const lvalue reference: both actions should get 1387f92157deSopenharmony_ci // a non-const lvalue reference if they want them. 1388f92157deSopenharmony_ci { 1389f92157deSopenharmony_ci struct InitialAction { 1390f92157deSopenharmony_ci void operator()(Obj&) const {} 1391f92157deSopenharmony_ci void operator()(Obj&&) const { FAIL() << "Unexpected call"; } 1392f92157deSopenharmony_ci }; 1393f92157deSopenharmony_ci 1394f92157deSopenharmony_ci MockFunction<void(Obj&)> mock; 1395f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1396f92157deSopenharmony_ci .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {})) 1397f92157deSopenharmony_ci .WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {})); 1398f92157deSopenharmony_ci 1399f92157deSopenharmony_ci Obj obj; 1400f92157deSopenharmony_ci mock.AsStdFunction()(obj); 1401f92157deSopenharmony_ci mock.AsStdFunction()(obj); 1402f92157deSopenharmony_ci } 1403f92157deSopenharmony_ci 1404f92157deSopenharmony_ci // Mock action accepts by rvalue reference: the initial actions should receive 1405f92157deSopenharmony_ci // a non-const lvalue reference if it wants it, and the final action an rvalue 1406f92157deSopenharmony_ci // reference. 1407f92157deSopenharmony_ci { 1408f92157deSopenharmony_ci struct InitialAction { 1409f92157deSopenharmony_ci void operator()(Obj&) const {} 1410f92157deSopenharmony_ci void operator()(Obj&&) const { FAIL() << "Unexpected call"; } 1411f92157deSopenharmony_ci }; 1412f92157deSopenharmony_ci 1413f92157deSopenharmony_ci MockFunction<void(Obj &&)> mock; 1414f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1415f92157deSopenharmony_ci .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})) 1416f92157deSopenharmony_ci .WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})); 1417f92157deSopenharmony_ci 1418f92157deSopenharmony_ci mock.AsStdFunction()(Obj{}); 1419f92157deSopenharmony_ci mock.AsStdFunction()(Obj{}); 1420f92157deSopenharmony_ci } 1421f92157deSopenharmony_ci 1422f92157deSopenharmony_ci // &&-qualified initial actions should also be allowed with WillOnce. 1423f92157deSopenharmony_ci { 1424f92157deSopenharmony_ci struct InitialAction { 1425f92157deSopenharmony_ci void operator()(Obj&) && {} 1426f92157deSopenharmony_ci }; 1427f92157deSopenharmony_ci 1428f92157deSopenharmony_ci MockFunction<void(Obj&)> mock; 1429f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1430f92157deSopenharmony_ci .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {})); 1431f92157deSopenharmony_ci 1432f92157deSopenharmony_ci Obj obj; 1433f92157deSopenharmony_ci mock.AsStdFunction()(obj); 1434f92157deSopenharmony_ci } 1435f92157deSopenharmony_ci 1436f92157deSopenharmony_ci { 1437f92157deSopenharmony_ci struct InitialAction { 1438f92157deSopenharmony_ci void operator()(Obj&) && {} 1439f92157deSopenharmony_ci }; 1440f92157deSopenharmony_ci 1441f92157deSopenharmony_ci MockFunction<void(Obj &&)> mock; 1442f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1443f92157deSopenharmony_ci .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})); 1444f92157deSopenharmony_ci 1445f92157deSopenharmony_ci mock.AsStdFunction()(Obj{}); 1446f92157deSopenharmony_ci } 1447f92157deSopenharmony_ci} 1448f92157deSopenharmony_ci 1449f92157deSopenharmony_ci// DoAll should support being used with type-erased Action objects, both through 1450f92157deSopenharmony_ci// WillOnce and WillRepeatedly. 1451f92157deSopenharmony_ciTEST(DoAll, SupportsTypeErasedActions) { 1452f92157deSopenharmony_ci // With only type-erased actions. 1453f92157deSopenharmony_ci const Action<void()> initial_action = [] {}; 1454f92157deSopenharmony_ci const Action<int()> final_action = [] { return 17; }; 1455f92157deSopenharmony_ci 1456f92157deSopenharmony_ci MockFunction<int()> mock; 1457f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1458f92157deSopenharmony_ci .WillOnce(DoAll(initial_action, initial_action, final_action)) 1459f92157deSopenharmony_ci .WillRepeatedly(DoAll(initial_action, initial_action, final_action)); 1460f92157deSopenharmony_ci 1461f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 1462f92157deSopenharmony_ci 1463f92157deSopenharmony_ci // With &&-qualified and move-only final action. 1464f92157deSopenharmony_ci { 1465f92157deSopenharmony_ci struct FinalAction { 1466f92157deSopenharmony_ci FinalAction() = default; 1467f92157deSopenharmony_ci FinalAction(FinalAction&&) = default; 1468f92157deSopenharmony_ci 1469f92157deSopenharmony_ci int operator()() && { return 17; } 1470f92157deSopenharmony_ci }; 1471f92157deSopenharmony_ci 1472f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1473f92157deSopenharmony_ci .WillOnce(DoAll(initial_action, initial_action, FinalAction{})); 1474f92157deSopenharmony_ci 1475f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 1476f92157deSopenharmony_ci } 1477f92157deSopenharmony_ci} 1478f92157deSopenharmony_ci 1479f92157deSopenharmony_ci// Tests using WithArgs and with an action that takes 1 argument. 1480f92157deSopenharmony_ciTEST(WithArgsTest, OneArg) { 1481f92157deSopenharmony_ci Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT 1482f92157deSopenharmony_ci EXPECT_TRUE(a.Perform(std::make_tuple(1.5, -1))); 1483f92157deSopenharmony_ci EXPECT_FALSE(a.Perform(std::make_tuple(1.5, 1))); 1484f92157deSopenharmony_ci} 1485f92157deSopenharmony_ci 1486f92157deSopenharmony_ci// Tests using WithArgs with an action that takes 2 arguments. 1487f92157deSopenharmony_ciTEST(WithArgsTest, TwoArgs) { 1488f92157deSopenharmony_ci Action<const char*(const char* s, double x, short n)> a = // NOLINT 1489f92157deSopenharmony_ci WithArgs<0, 2>(Invoke(Binary)); 1490f92157deSopenharmony_ci const char s[] = "Hello"; 1491f92157deSopenharmony_ci EXPECT_EQ(s + 2, a.Perform(std::make_tuple(CharPtr(s), 0.5, Short(2)))); 1492f92157deSopenharmony_ci} 1493f92157deSopenharmony_ci 1494f92157deSopenharmony_cistruct ConcatAll { 1495f92157deSopenharmony_ci std::string operator()() const { return {}; } 1496f92157deSopenharmony_ci template <typename... I> 1497f92157deSopenharmony_ci std::string operator()(const char* a, I... i) const { 1498f92157deSopenharmony_ci return a + ConcatAll()(i...); 1499f92157deSopenharmony_ci } 1500f92157deSopenharmony_ci}; 1501f92157deSopenharmony_ci 1502f92157deSopenharmony_ci// Tests using WithArgs with an action that takes 10 arguments. 1503f92157deSopenharmony_ciTEST(WithArgsTest, TenArgs) { 1504f92157deSopenharmony_ci Action<std::string(const char*, const char*, const char*, const char*)> a = 1505f92157deSopenharmony_ci WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(ConcatAll{})); 1506f92157deSopenharmony_ci EXPECT_EQ("0123210123", 1507f92157deSopenharmony_ci a.Perform(std::make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), 1508f92157deSopenharmony_ci CharPtr("3")))); 1509f92157deSopenharmony_ci} 1510f92157deSopenharmony_ci 1511f92157deSopenharmony_ci// Tests using WithArgs with an action that is not Invoke(). 1512f92157deSopenharmony_ciclass SubtractAction : public ActionInterface<int(int, int)> { 1513f92157deSopenharmony_ci public: 1514f92157deSopenharmony_ci int Perform(const std::tuple<int, int>& args) override { 1515f92157deSopenharmony_ci return std::get<0>(args) - std::get<1>(args); 1516f92157deSopenharmony_ci } 1517f92157deSopenharmony_ci}; 1518f92157deSopenharmony_ci 1519f92157deSopenharmony_ciTEST(WithArgsTest, NonInvokeAction) { 1520f92157deSopenharmony_ci Action<int(const std::string&, int, int)> a = 1521f92157deSopenharmony_ci WithArgs<2, 1>(MakeAction(new SubtractAction)); 1522f92157deSopenharmony_ci std::tuple<std::string, int, int> dummy = 1523f92157deSopenharmony_ci std::make_tuple(std::string("hi"), 2, 10); 1524f92157deSopenharmony_ci EXPECT_EQ(8, a.Perform(dummy)); 1525f92157deSopenharmony_ci} 1526f92157deSopenharmony_ci 1527f92157deSopenharmony_ci// Tests using WithArgs to pass all original arguments in the original order. 1528f92157deSopenharmony_ciTEST(WithArgsTest, Identity) { 1529f92157deSopenharmony_ci Action<int(int x, char y, short z)> a = // NOLINT 1530f92157deSopenharmony_ci WithArgs<0, 1, 2>(Invoke(Ternary)); 1531f92157deSopenharmony_ci EXPECT_EQ(123, a.Perform(std::make_tuple(100, Char(20), Short(3)))); 1532f92157deSopenharmony_ci} 1533f92157deSopenharmony_ci 1534f92157deSopenharmony_ci// Tests using WithArgs with repeated arguments. 1535f92157deSopenharmony_ciTEST(WithArgsTest, RepeatedArguments) { 1536f92157deSopenharmony_ci Action<int(bool, int m, int n)> a = // NOLINT 1537f92157deSopenharmony_ci WithArgs<1, 1, 1, 1>(Invoke(SumOf4)); 1538f92157deSopenharmony_ci EXPECT_EQ(4, a.Perform(std::make_tuple(false, 1, 10))); 1539f92157deSopenharmony_ci} 1540f92157deSopenharmony_ci 1541f92157deSopenharmony_ci// Tests using WithArgs with reversed argument order. 1542f92157deSopenharmony_ciTEST(WithArgsTest, ReversedArgumentOrder) { 1543f92157deSopenharmony_ci Action<const char*(short n, const char* input)> a = // NOLINT 1544f92157deSopenharmony_ci WithArgs<1, 0>(Invoke(Binary)); 1545f92157deSopenharmony_ci const char s[] = "Hello"; 1546f92157deSopenharmony_ci EXPECT_EQ(s + 2, a.Perform(std::make_tuple(Short(2), CharPtr(s)))); 1547f92157deSopenharmony_ci} 1548f92157deSopenharmony_ci 1549f92157deSopenharmony_ci// Tests using WithArgs with compatible, but not identical, argument types. 1550f92157deSopenharmony_ciTEST(WithArgsTest, ArgsOfCompatibleTypes) { 1551f92157deSopenharmony_ci Action<long(short x, char y, double z, char c)> a = // NOLINT 1552f92157deSopenharmony_ci WithArgs<0, 1, 3>(Invoke(Ternary)); 1553f92157deSopenharmony_ci EXPECT_EQ(123, 1554f92157deSopenharmony_ci a.Perform(std::make_tuple(Short(100), Char(20), 5.6, Char(3)))); 1555f92157deSopenharmony_ci} 1556f92157deSopenharmony_ci 1557f92157deSopenharmony_ci// Tests using WithArgs with an action that returns void. 1558f92157deSopenharmony_ciTEST(WithArgsTest, VoidAction) { 1559f92157deSopenharmony_ci Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary)); 1560f92157deSopenharmony_ci g_done = false; 1561f92157deSopenharmony_ci a.Perform(std::make_tuple(1.5, 'a', 3)); 1562f92157deSopenharmony_ci EXPECT_TRUE(g_done); 1563f92157deSopenharmony_ci} 1564f92157deSopenharmony_ci 1565f92157deSopenharmony_ciTEST(WithArgsTest, ReturnReference) { 1566f92157deSopenharmony_ci Action<int&(int&, void*)> aa = WithArgs<0>([](int& a) -> int& { return a; }); 1567f92157deSopenharmony_ci int i = 0; 1568f92157deSopenharmony_ci const int& res = aa.Perform(std::forward_as_tuple(i, nullptr)); 1569f92157deSopenharmony_ci EXPECT_EQ(&i, &res); 1570f92157deSopenharmony_ci} 1571f92157deSopenharmony_ci 1572f92157deSopenharmony_ciTEST(WithArgsTest, InnerActionWithConversion) { 1573f92157deSopenharmony_ci Action<Derived*()> inner = [] { return nullptr; }; 1574f92157deSopenharmony_ci 1575f92157deSopenharmony_ci MockFunction<Base*(double)> mock; 1576f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 1577f92157deSopenharmony_ci .WillOnce(WithoutArgs(inner)) 1578f92157deSopenharmony_ci .WillRepeatedly(WithoutArgs(inner)); 1579f92157deSopenharmony_ci 1580f92157deSopenharmony_ci EXPECT_EQ(nullptr, mock.AsStdFunction()(1.1)); 1581f92157deSopenharmony_ci EXPECT_EQ(nullptr, mock.AsStdFunction()(1.1)); 1582f92157deSopenharmony_ci} 1583f92157deSopenharmony_ci 1584f92157deSopenharmony_ci// It should be possible to use an &&-qualified inner action as long as the 1585f92157deSopenharmony_ci// whole shebang is used as an rvalue with WillOnce. 1586f92157deSopenharmony_ciTEST(WithArgsTest, RefQualifiedInnerAction) { 1587f92157deSopenharmony_ci struct SomeAction { 1588f92157deSopenharmony_ci int operator()(const int arg) && { 1589f92157deSopenharmony_ci EXPECT_EQ(17, arg); 1590f92157deSopenharmony_ci return 19; 1591f92157deSopenharmony_ci } 1592f92157deSopenharmony_ci }; 1593f92157deSopenharmony_ci 1594f92157deSopenharmony_ci MockFunction<int(int, int)> mock; 1595f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(WithArg<1>(SomeAction{})); 1596f92157deSopenharmony_ci EXPECT_EQ(19, mock.AsStdFunction()(0, 17)); 1597f92157deSopenharmony_ci} 1598f92157deSopenharmony_ci 1599f92157deSopenharmony_ci#if !GTEST_OS_WINDOWS_MOBILE 1600f92157deSopenharmony_ci 1601f92157deSopenharmony_ciclass SetErrnoAndReturnTest : public testing::Test { 1602f92157deSopenharmony_ci protected: 1603f92157deSopenharmony_ci void SetUp() override { errno = 0; } 1604f92157deSopenharmony_ci void TearDown() override { errno = 0; } 1605f92157deSopenharmony_ci}; 1606f92157deSopenharmony_ci 1607f92157deSopenharmony_ciTEST_F(SetErrnoAndReturnTest, Int) { 1608f92157deSopenharmony_ci Action<int(void)> a = SetErrnoAndReturn(ENOTTY, -5); 1609f92157deSopenharmony_ci EXPECT_EQ(-5, a.Perform(std::make_tuple())); 1610f92157deSopenharmony_ci EXPECT_EQ(ENOTTY, errno); 1611f92157deSopenharmony_ci} 1612f92157deSopenharmony_ci 1613f92157deSopenharmony_ciTEST_F(SetErrnoAndReturnTest, Ptr) { 1614f92157deSopenharmony_ci int x; 1615f92157deSopenharmony_ci Action<int*(void)> a = SetErrnoAndReturn(ENOTTY, &x); 1616f92157deSopenharmony_ci EXPECT_EQ(&x, a.Perform(std::make_tuple())); 1617f92157deSopenharmony_ci EXPECT_EQ(ENOTTY, errno); 1618f92157deSopenharmony_ci} 1619f92157deSopenharmony_ci 1620f92157deSopenharmony_ciTEST_F(SetErrnoAndReturnTest, CompatibleTypes) { 1621f92157deSopenharmony_ci Action<double()> a = SetErrnoAndReturn(EINVAL, 5); 1622f92157deSopenharmony_ci EXPECT_DOUBLE_EQ(5.0, a.Perform(std::make_tuple())); 1623f92157deSopenharmony_ci EXPECT_EQ(EINVAL, errno); 1624f92157deSopenharmony_ci} 1625f92157deSopenharmony_ci 1626f92157deSopenharmony_ci#endif // !GTEST_OS_WINDOWS_MOBILE 1627f92157deSopenharmony_ci 1628f92157deSopenharmony_ci// Tests ByRef(). 1629f92157deSopenharmony_ci 1630f92157deSopenharmony_ci// Tests that the result of ByRef() is copyable. 1631f92157deSopenharmony_ciTEST(ByRefTest, IsCopyable) { 1632f92157deSopenharmony_ci const std::string s1 = "Hi"; 1633f92157deSopenharmony_ci const std::string s2 = "Hello"; 1634f92157deSopenharmony_ci 1635f92157deSopenharmony_ci auto ref_wrapper = ByRef(s1); 1636f92157deSopenharmony_ci const std::string& r1 = ref_wrapper; 1637f92157deSopenharmony_ci EXPECT_EQ(&s1, &r1); 1638f92157deSopenharmony_ci 1639f92157deSopenharmony_ci // Assigns a new value to ref_wrapper. 1640f92157deSopenharmony_ci ref_wrapper = ByRef(s2); 1641f92157deSopenharmony_ci const std::string& r2 = ref_wrapper; 1642f92157deSopenharmony_ci EXPECT_EQ(&s2, &r2); 1643f92157deSopenharmony_ci 1644f92157deSopenharmony_ci auto ref_wrapper1 = ByRef(s1); 1645f92157deSopenharmony_ci // Copies ref_wrapper1 to ref_wrapper. 1646f92157deSopenharmony_ci ref_wrapper = ref_wrapper1; 1647f92157deSopenharmony_ci const std::string& r3 = ref_wrapper; 1648f92157deSopenharmony_ci EXPECT_EQ(&s1, &r3); 1649f92157deSopenharmony_ci} 1650f92157deSopenharmony_ci 1651f92157deSopenharmony_ci// Tests using ByRef() on a const value. 1652f92157deSopenharmony_ciTEST(ByRefTest, ConstValue) { 1653f92157deSopenharmony_ci const int n = 0; 1654f92157deSopenharmony_ci // int& ref = ByRef(n); // This shouldn't compile - we have a 1655f92157deSopenharmony_ci // negative compilation test to catch it. 1656f92157deSopenharmony_ci const int& const_ref = ByRef(n); 1657f92157deSopenharmony_ci EXPECT_EQ(&n, &const_ref); 1658f92157deSopenharmony_ci} 1659f92157deSopenharmony_ci 1660f92157deSopenharmony_ci// Tests using ByRef() on a non-const value. 1661f92157deSopenharmony_ciTEST(ByRefTest, NonConstValue) { 1662f92157deSopenharmony_ci int n = 0; 1663f92157deSopenharmony_ci 1664f92157deSopenharmony_ci // ByRef(n) can be used as either an int&, 1665f92157deSopenharmony_ci int& ref = ByRef(n); 1666f92157deSopenharmony_ci EXPECT_EQ(&n, &ref); 1667f92157deSopenharmony_ci 1668f92157deSopenharmony_ci // or a const int&. 1669f92157deSopenharmony_ci const int& const_ref = ByRef(n); 1670f92157deSopenharmony_ci EXPECT_EQ(&n, &const_ref); 1671f92157deSopenharmony_ci} 1672f92157deSopenharmony_ci 1673f92157deSopenharmony_ci// Tests explicitly specifying the type when using ByRef(). 1674f92157deSopenharmony_ciTEST(ByRefTest, ExplicitType) { 1675f92157deSopenharmony_ci int n = 0; 1676f92157deSopenharmony_ci const int& r1 = ByRef<const int>(n); 1677f92157deSopenharmony_ci EXPECT_EQ(&n, &r1); 1678f92157deSopenharmony_ci 1679f92157deSopenharmony_ci // ByRef<char>(n); // This shouldn't compile - we have a negative 1680f92157deSopenharmony_ci // compilation test to catch it. 1681f92157deSopenharmony_ci 1682f92157deSopenharmony_ci Derived d; 1683f92157deSopenharmony_ci Derived& r2 = ByRef<Derived>(d); 1684f92157deSopenharmony_ci EXPECT_EQ(&d, &r2); 1685f92157deSopenharmony_ci 1686f92157deSopenharmony_ci const Derived& r3 = ByRef<const Derived>(d); 1687f92157deSopenharmony_ci EXPECT_EQ(&d, &r3); 1688f92157deSopenharmony_ci 1689f92157deSopenharmony_ci Base& r4 = ByRef<Base>(d); 1690f92157deSopenharmony_ci EXPECT_EQ(&d, &r4); 1691f92157deSopenharmony_ci 1692f92157deSopenharmony_ci const Base& r5 = ByRef<const Base>(d); 1693f92157deSopenharmony_ci EXPECT_EQ(&d, &r5); 1694f92157deSopenharmony_ci 1695f92157deSopenharmony_ci // The following shouldn't compile - we have a negative compilation 1696f92157deSopenharmony_ci // test for it. 1697f92157deSopenharmony_ci // 1698f92157deSopenharmony_ci // Base b; 1699f92157deSopenharmony_ci // ByRef<Derived>(b); 1700f92157deSopenharmony_ci} 1701f92157deSopenharmony_ci 1702f92157deSopenharmony_ci// Tests that Google Mock prints expression ByRef(x) as a reference to x. 1703f92157deSopenharmony_ciTEST(ByRefTest, PrintsCorrectly) { 1704f92157deSopenharmony_ci int n = 42; 1705f92157deSopenharmony_ci ::std::stringstream expected, actual; 1706f92157deSopenharmony_ci testing::internal::UniversalPrinter<const int&>::Print(n, &expected); 1707f92157deSopenharmony_ci testing::internal::UniversalPrint(ByRef(n), &actual); 1708f92157deSopenharmony_ci EXPECT_EQ(expected.str(), actual.str()); 1709f92157deSopenharmony_ci} 1710f92157deSopenharmony_ci 1711f92157deSopenharmony_cistruct UnaryConstructorClass { 1712f92157deSopenharmony_ci explicit UnaryConstructorClass(int v) : value(v) {} 1713f92157deSopenharmony_ci int value; 1714f92157deSopenharmony_ci}; 1715f92157deSopenharmony_ci 1716f92157deSopenharmony_ci// Tests using ReturnNew() with a unary constructor. 1717f92157deSopenharmony_ciTEST(ReturnNewTest, Unary) { 1718f92157deSopenharmony_ci Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000); 1719f92157deSopenharmony_ci UnaryConstructorClass* c = a.Perform(std::make_tuple()); 1720f92157deSopenharmony_ci EXPECT_EQ(4000, c->value); 1721f92157deSopenharmony_ci delete c; 1722f92157deSopenharmony_ci} 1723f92157deSopenharmony_ci 1724f92157deSopenharmony_ciTEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) { 1725f92157deSopenharmony_ci Action<UnaryConstructorClass*(bool, int)> a = 1726f92157deSopenharmony_ci ReturnNew<UnaryConstructorClass>(4000); 1727f92157deSopenharmony_ci UnaryConstructorClass* c = a.Perform(std::make_tuple(false, 5)); 1728f92157deSopenharmony_ci EXPECT_EQ(4000, c->value); 1729f92157deSopenharmony_ci delete c; 1730f92157deSopenharmony_ci} 1731f92157deSopenharmony_ci 1732f92157deSopenharmony_ciTEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) { 1733f92157deSopenharmony_ci Action<const UnaryConstructorClass*()> a = 1734f92157deSopenharmony_ci ReturnNew<UnaryConstructorClass>(4000); 1735f92157deSopenharmony_ci const UnaryConstructorClass* c = a.Perform(std::make_tuple()); 1736f92157deSopenharmony_ci EXPECT_EQ(4000, c->value); 1737f92157deSopenharmony_ci delete c; 1738f92157deSopenharmony_ci} 1739f92157deSopenharmony_ci 1740f92157deSopenharmony_ciclass TenArgConstructorClass { 1741f92157deSopenharmony_ci public: 1742f92157deSopenharmony_ci TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, int a6, int a7, 1743f92157deSopenharmony_ci int a8, int a9, int a10) 1744f92157deSopenharmony_ci : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {} 1745f92157deSopenharmony_ci int value_; 1746f92157deSopenharmony_ci}; 1747f92157deSopenharmony_ci 1748f92157deSopenharmony_ci// Tests using ReturnNew() with a 10-argument constructor. 1749f92157deSopenharmony_ciTEST(ReturnNewTest, ConstructorThatTakes10Arguments) { 1750f92157deSopenharmony_ci Action<TenArgConstructorClass*()> a = ReturnNew<TenArgConstructorClass>( 1751f92157deSopenharmony_ci 1000000000, 200000000, 30000000, 4000000, 500000, 60000, 7000, 800, 90, 1752f92157deSopenharmony_ci 0); 1753f92157deSopenharmony_ci TenArgConstructorClass* c = a.Perform(std::make_tuple()); 1754f92157deSopenharmony_ci EXPECT_EQ(1234567890, c->value_); 1755f92157deSopenharmony_ci delete c; 1756f92157deSopenharmony_ci} 1757f92157deSopenharmony_ci 1758f92157deSopenharmony_cistd::unique_ptr<int> UniquePtrSource() { 1759f92157deSopenharmony_ci return std::unique_ptr<int>(new int(19)); 1760f92157deSopenharmony_ci} 1761f92157deSopenharmony_ci 1762f92157deSopenharmony_cistd::vector<std::unique_ptr<int>> VectorUniquePtrSource() { 1763f92157deSopenharmony_ci std::vector<std::unique_ptr<int>> out; 1764f92157deSopenharmony_ci out.emplace_back(new int(7)); 1765f92157deSopenharmony_ci return out; 1766f92157deSopenharmony_ci} 1767f92157deSopenharmony_ci 1768f92157deSopenharmony_ciTEST(MockMethodTest, CanReturnMoveOnlyValue_Return) { 1769f92157deSopenharmony_ci MockClass mock; 1770f92157deSopenharmony_ci std::unique_ptr<int> i(new int(19)); 1771f92157deSopenharmony_ci EXPECT_CALL(mock, MakeUnique()).WillOnce(Return(ByMove(std::move(i)))); 1772f92157deSopenharmony_ci EXPECT_CALL(mock, MakeVectorUnique()) 1773f92157deSopenharmony_ci .WillOnce(Return(ByMove(VectorUniquePtrSource()))); 1774f92157deSopenharmony_ci Derived* d = new Derived; 1775f92157deSopenharmony_ci EXPECT_CALL(mock, MakeUniqueBase()) 1776f92157deSopenharmony_ci .WillOnce(Return(ByMove(std::unique_ptr<Derived>(d)))); 1777f92157deSopenharmony_ci 1778f92157deSopenharmony_ci std::unique_ptr<int> result1 = mock.MakeUnique(); 1779f92157deSopenharmony_ci EXPECT_EQ(19, *result1); 1780f92157deSopenharmony_ci 1781f92157deSopenharmony_ci std::vector<std::unique_ptr<int>> vresult = mock.MakeVectorUnique(); 1782f92157deSopenharmony_ci EXPECT_EQ(1u, vresult.size()); 1783f92157deSopenharmony_ci EXPECT_NE(nullptr, vresult[0]); 1784f92157deSopenharmony_ci EXPECT_EQ(7, *vresult[0]); 1785f92157deSopenharmony_ci 1786f92157deSopenharmony_ci std::unique_ptr<Base> result2 = mock.MakeUniqueBase(); 1787f92157deSopenharmony_ci EXPECT_EQ(d, result2.get()); 1788f92157deSopenharmony_ci} 1789f92157deSopenharmony_ci 1790f92157deSopenharmony_ciTEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) { 1791f92157deSopenharmony_ci testing::MockFunction<void()> mock_function; 1792f92157deSopenharmony_ci MockClass mock; 1793f92157deSopenharmony_ci std::unique_ptr<int> i(new int(19)); 1794f92157deSopenharmony_ci EXPECT_CALL(mock_function, Call()); 1795f92157deSopenharmony_ci EXPECT_CALL(mock, MakeUnique()) 1796f92157deSopenharmony_ci .WillOnce(DoAll(InvokeWithoutArgs(&mock_function, 1797f92157deSopenharmony_ci &testing::MockFunction<void()>::Call), 1798f92157deSopenharmony_ci Return(ByMove(std::move(i))))); 1799f92157deSopenharmony_ci 1800f92157deSopenharmony_ci std::unique_ptr<int> result1 = mock.MakeUnique(); 1801f92157deSopenharmony_ci EXPECT_EQ(19, *result1); 1802f92157deSopenharmony_ci} 1803f92157deSopenharmony_ci 1804f92157deSopenharmony_ciTEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) { 1805f92157deSopenharmony_ci MockClass mock; 1806f92157deSopenharmony_ci 1807f92157deSopenharmony_ci // Check default value 1808f92157deSopenharmony_ci DefaultValue<std::unique_ptr<int>>::SetFactory( 1809f92157deSopenharmony_ci [] { return std::unique_ptr<int>(new int(42)); }); 1810f92157deSopenharmony_ci EXPECT_EQ(42, *mock.MakeUnique()); 1811f92157deSopenharmony_ci 1812f92157deSopenharmony_ci EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource)); 1813f92157deSopenharmony_ci EXPECT_CALL(mock, MakeVectorUnique()) 1814f92157deSopenharmony_ci .WillRepeatedly(Invoke(VectorUniquePtrSource)); 1815f92157deSopenharmony_ci std::unique_ptr<int> result1 = mock.MakeUnique(); 1816f92157deSopenharmony_ci EXPECT_EQ(19, *result1); 1817f92157deSopenharmony_ci std::unique_ptr<int> result2 = mock.MakeUnique(); 1818f92157deSopenharmony_ci EXPECT_EQ(19, *result2); 1819f92157deSopenharmony_ci EXPECT_NE(result1, result2); 1820f92157deSopenharmony_ci 1821f92157deSopenharmony_ci std::vector<std::unique_ptr<int>> vresult = mock.MakeVectorUnique(); 1822f92157deSopenharmony_ci EXPECT_EQ(1u, vresult.size()); 1823f92157deSopenharmony_ci EXPECT_NE(nullptr, vresult[0]); 1824f92157deSopenharmony_ci EXPECT_EQ(7, *vresult[0]); 1825f92157deSopenharmony_ci} 1826f92157deSopenharmony_ci 1827f92157deSopenharmony_ciTEST(MockMethodTest, CanTakeMoveOnlyValue) { 1828f92157deSopenharmony_ci MockClass mock; 1829f92157deSopenharmony_ci auto make = [](int i) { return std::unique_ptr<int>(new int(i)); }; 1830f92157deSopenharmony_ci 1831f92157deSopenharmony_ci EXPECT_CALL(mock, TakeUnique(_)).WillRepeatedly([](std::unique_ptr<int> i) { 1832f92157deSopenharmony_ci return *i; 1833f92157deSopenharmony_ci }); 1834f92157deSopenharmony_ci // DoAll() does not compile, since it would move from its arguments twice. 1835f92157deSopenharmony_ci // EXPECT_CALL(mock, TakeUnique(_, _)) 1836f92157deSopenharmony_ci // .WillRepeatedly(DoAll(Invoke([](std::unique_ptr<int> j) {}), 1837f92157deSopenharmony_ci // Return(1))); 1838f92157deSopenharmony_ci EXPECT_CALL(mock, TakeUnique(testing::Pointee(7))) 1839f92157deSopenharmony_ci .WillOnce(Return(-7)) 1840f92157deSopenharmony_ci .RetiresOnSaturation(); 1841f92157deSopenharmony_ci EXPECT_CALL(mock, TakeUnique(testing::IsNull())) 1842f92157deSopenharmony_ci .WillOnce(Return(-1)) 1843f92157deSopenharmony_ci .RetiresOnSaturation(); 1844f92157deSopenharmony_ci 1845f92157deSopenharmony_ci EXPECT_EQ(5, mock.TakeUnique(make(5))); 1846f92157deSopenharmony_ci EXPECT_EQ(-7, mock.TakeUnique(make(7))); 1847f92157deSopenharmony_ci EXPECT_EQ(7, mock.TakeUnique(make(7))); 1848f92157deSopenharmony_ci EXPECT_EQ(7, mock.TakeUnique(make(7))); 1849f92157deSopenharmony_ci EXPECT_EQ(-1, mock.TakeUnique({})); 1850f92157deSopenharmony_ci 1851f92157deSopenharmony_ci // Some arguments are moved, some passed by reference. 1852f92157deSopenharmony_ci auto lvalue = make(6); 1853f92157deSopenharmony_ci EXPECT_CALL(mock, TakeUnique(_, _)) 1854f92157deSopenharmony_ci .WillOnce([](const std::unique_ptr<int>& i, std::unique_ptr<int> j) { 1855f92157deSopenharmony_ci return *i * *j; 1856f92157deSopenharmony_ci }); 1857f92157deSopenharmony_ci EXPECT_EQ(42, mock.TakeUnique(lvalue, make(7))); 1858f92157deSopenharmony_ci 1859f92157deSopenharmony_ci // The unique_ptr can be saved by the action. 1860f92157deSopenharmony_ci std::unique_ptr<int> saved; 1861f92157deSopenharmony_ci EXPECT_CALL(mock, TakeUnique(_)).WillOnce([&saved](std::unique_ptr<int> i) { 1862f92157deSopenharmony_ci saved = std::move(i); 1863f92157deSopenharmony_ci return 0; 1864f92157deSopenharmony_ci }); 1865f92157deSopenharmony_ci EXPECT_EQ(0, mock.TakeUnique(make(42))); 1866f92157deSopenharmony_ci EXPECT_EQ(42, *saved); 1867f92157deSopenharmony_ci} 1868f92157deSopenharmony_ci 1869f92157deSopenharmony_ci// It should be possible to use callables with an &&-qualified call operator 1870f92157deSopenharmony_ci// with WillOnce, since they will be called only once. This allows actions to 1871f92157deSopenharmony_ci// contain and manipulate move-only types. 1872f92157deSopenharmony_ciTEST(MockMethodTest, ActionHasRvalueRefQualifiedCallOperator) { 1873f92157deSopenharmony_ci struct Return17 { 1874f92157deSopenharmony_ci int operator()() && { return 17; } 1875f92157deSopenharmony_ci }; 1876f92157deSopenharmony_ci 1877f92157deSopenharmony_ci // Action is directly compatible with mocked function type. 1878f92157deSopenharmony_ci { 1879f92157deSopenharmony_ci MockFunction<int()> mock; 1880f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(Return17()); 1881f92157deSopenharmony_ci 1882f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 1883f92157deSopenharmony_ci } 1884f92157deSopenharmony_ci 1885f92157deSopenharmony_ci // Action doesn't want mocked function arguments. 1886f92157deSopenharmony_ci { 1887f92157deSopenharmony_ci MockFunction<int(int)> mock; 1888f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(Return17()); 1889f92157deSopenharmony_ci 1890f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()(0)); 1891f92157deSopenharmony_ci } 1892f92157deSopenharmony_ci} 1893f92157deSopenharmony_ci 1894f92157deSopenharmony_ci// Edge case: if an action has both a const-qualified and an &&-qualified call 1895f92157deSopenharmony_ci// operator, there should be no "ambiguous call" errors. The &&-qualified 1896f92157deSopenharmony_ci// operator should be used by WillOnce (since it doesn't need to retain the 1897f92157deSopenharmony_ci// action beyond one call), and the const-qualified one by WillRepeatedly. 1898f92157deSopenharmony_ciTEST(MockMethodTest, ActionHasMultipleCallOperators) { 1899f92157deSopenharmony_ci struct ReturnInt { 1900f92157deSopenharmony_ci int operator()() && { return 17; } 1901f92157deSopenharmony_ci int operator()() const& { return 19; } 1902f92157deSopenharmony_ci }; 1903f92157deSopenharmony_ci 1904f92157deSopenharmony_ci // Directly compatible with mocked function type. 1905f92157deSopenharmony_ci { 1906f92157deSopenharmony_ci MockFunction<int()> mock; 1907f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt()); 1908f92157deSopenharmony_ci 1909f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 1910f92157deSopenharmony_ci EXPECT_EQ(19, mock.AsStdFunction()()); 1911f92157deSopenharmony_ci EXPECT_EQ(19, mock.AsStdFunction()()); 1912f92157deSopenharmony_ci } 1913f92157deSopenharmony_ci 1914f92157deSopenharmony_ci // Ignores function arguments. 1915f92157deSopenharmony_ci { 1916f92157deSopenharmony_ci MockFunction<int(int)> mock; 1917f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt()); 1918f92157deSopenharmony_ci 1919f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()(0)); 1920f92157deSopenharmony_ci EXPECT_EQ(19, mock.AsStdFunction()(0)); 1921f92157deSopenharmony_ci EXPECT_EQ(19, mock.AsStdFunction()(0)); 1922f92157deSopenharmony_ci } 1923f92157deSopenharmony_ci} 1924f92157deSopenharmony_ci 1925f92157deSopenharmony_ci// WillOnce should have no problem coping with a move-only action, whether it is 1926f92157deSopenharmony_ci// &&-qualified or not. 1927f92157deSopenharmony_ciTEST(MockMethodTest, MoveOnlyAction) { 1928f92157deSopenharmony_ci // &&-qualified 1929f92157deSopenharmony_ci { 1930f92157deSopenharmony_ci struct Return17 { 1931f92157deSopenharmony_ci Return17() = default; 1932f92157deSopenharmony_ci Return17(Return17&&) = default; 1933f92157deSopenharmony_ci 1934f92157deSopenharmony_ci Return17(const Return17&) = delete; 1935f92157deSopenharmony_ci Return17 operator=(const Return17&) = delete; 1936f92157deSopenharmony_ci 1937f92157deSopenharmony_ci int operator()() && { return 17; } 1938f92157deSopenharmony_ci }; 1939f92157deSopenharmony_ci 1940f92157deSopenharmony_ci MockFunction<int()> mock; 1941f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(Return17()); 1942f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 1943f92157deSopenharmony_ci } 1944f92157deSopenharmony_ci 1945f92157deSopenharmony_ci // Not &&-qualified 1946f92157deSopenharmony_ci { 1947f92157deSopenharmony_ci struct Return17 { 1948f92157deSopenharmony_ci Return17() = default; 1949f92157deSopenharmony_ci Return17(Return17&&) = default; 1950f92157deSopenharmony_ci 1951f92157deSopenharmony_ci Return17(const Return17&) = delete; 1952f92157deSopenharmony_ci Return17 operator=(const Return17&) = delete; 1953f92157deSopenharmony_ci 1954f92157deSopenharmony_ci int operator()() const { return 17; } 1955f92157deSopenharmony_ci }; 1956f92157deSopenharmony_ci 1957f92157deSopenharmony_ci MockFunction<int()> mock; 1958f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(Return17()); 1959f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 1960f92157deSopenharmony_ci } 1961f92157deSopenharmony_ci} 1962f92157deSopenharmony_ci 1963f92157deSopenharmony_ci// It should be possible to use an action that returns a value with a mock 1964f92157deSopenharmony_ci// function that doesn't, both through WillOnce and WillRepeatedly. 1965f92157deSopenharmony_ciTEST(MockMethodTest, ActionReturnsIgnoredValue) { 1966f92157deSopenharmony_ci struct ReturnInt { 1967f92157deSopenharmony_ci int operator()() const { return 0; } 1968f92157deSopenharmony_ci }; 1969f92157deSopenharmony_ci 1970f92157deSopenharmony_ci MockFunction<void()> mock; 1971f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt()); 1972f92157deSopenharmony_ci 1973f92157deSopenharmony_ci mock.AsStdFunction()(); 1974f92157deSopenharmony_ci mock.AsStdFunction()(); 1975f92157deSopenharmony_ci} 1976f92157deSopenharmony_ci 1977f92157deSopenharmony_ci// Despite the fanciness around move-only actions and so on, it should still be 1978f92157deSopenharmony_ci// possible to hand an lvalue reference to a copyable action to WillOnce. 1979f92157deSopenharmony_ciTEST(MockMethodTest, WillOnceCanAcceptLvalueReference) { 1980f92157deSopenharmony_ci MockFunction<int()> mock; 1981f92157deSopenharmony_ci 1982f92157deSopenharmony_ci const auto action = [] { return 17; }; 1983f92157deSopenharmony_ci EXPECT_CALL(mock, Call).WillOnce(action); 1984f92157deSopenharmony_ci 1985f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 1986f92157deSopenharmony_ci} 1987f92157deSopenharmony_ci 1988f92157deSopenharmony_ci// A callable that doesn't use SFINAE to restrict its call operator's overload 1989f92157deSopenharmony_ci// set, but is still picky about which arguments it will accept. 1990f92157deSopenharmony_cistruct StaticAssertSingleArgument { 1991f92157deSopenharmony_ci template <typename... Args> 1992f92157deSopenharmony_ci static constexpr bool CheckArgs() { 1993f92157deSopenharmony_ci static_assert(sizeof...(Args) == 1, ""); 1994f92157deSopenharmony_ci return true; 1995f92157deSopenharmony_ci } 1996f92157deSopenharmony_ci 1997f92157deSopenharmony_ci template <typename... Args, bool = CheckArgs<Args...>()> 1998f92157deSopenharmony_ci int operator()(Args...) const { 1999f92157deSopenharmony_ci return 17; 2000f92157deSopenharmony_ci } 2001f92157deSopenharmony_ci}; 2002f92157deSopenharmony_ci 2003f92157deSopenharmony_ci// WillOnce and WillRepeatedly should both work fine with naïve implementations 2004f92157deSopenharmony_ci// of actions that don't use SFINAE to limit the overload set for their call 2005f92157deSopenharmony_ci// operator. If they are compatible with the actual mocked signature, we 2006f92157deSopenharmony_ci// shouldn't probe them with no arguments and trip a static_assert. 2007f92157deSopenharmony_ciTEST(MockMethodTest, ActionSwallowsAllArguments) { 2008f92157deSopenharmony_ci MockFunction<int(int)> mock; 2009f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 2010f92157deSopenharmony_ci .WillOnce(StaticAssertSingleArgument{}) 2011f92157deSopenharmony_ci .WillRepeatedly(StaticAssertSingleArgument{}); 2012f92157deSopenharmony_ci 2013f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()(0)); 2014f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()(0)); 2015f92157deSopenharmony_ci} 2016f92157deSopenharmony_ci 2017f92157deSopenharmony_cistruct ActionWithTemplatedConversionOperators { 2018f92157deSopenharmony_ci template <typename... Args> 2019f92157deSopenharmony_ci operator OnceAction<int(Args...)>() && { // NOLINT 2020f92157deSopenharmony_ci return [] { return 17; }; 2021f92157deSopenharmony_ci } 2022f92157deSopenharmony_ci 2023f92157deSopenharmony_ci template <typename... Args> 2024f92157deSopenharmony_ci operator Action<int(Args...)>() const { // NOLINT 2025f92157deSopenharmony_ci return [] { return 19; }; 2026f92157deSopenharmony_ci } 2027f92157deSopenharmony_ci}; 2028f92157deSopenharmony_ci 2029f92157deSopenharmony_ci// It should be fine to hand both WillOnce and WillRepeatedly a function that 2030f92157deSopenharmony_ci// defines templated conversion operators to OnceAction and Action. WillOnce 2031f92157deSopenharmony_ci// should prefer the OnceAction version. 2032f92157deSopenharmony_ciTEST(MockMethodTest, ActionHasTemplatedConversionOperators) { 2033f92157deSopenharmony_ci MockFunction<int()> mock; 2034f92157deSopenharmony_ci EXPECT_CALL(mock, Call) 2035f92157deSopenharmony_ci .WillOnce(ActionWithTemplatedConversionOperators{}) 2036f92157deSopenharmony_ci .WillRepeatedly(ActionWithTemplatedConversionOperators{}); 2037f92157deSopenharmony_ci 2038f92157deSopenharmony_ci EXPECT_EQ(17, mock.AsStdFunction()()); 2039f92157deSopenharmony_ci EXPECT_EQ(19, mock.AsStdFunction()()); 2040f92157deSopenharmony_ci} 2041f92157deSopenharmony_ci 2042f92157deSopenharmony_ci// Tests for std::function based action. 2043f92157deSopenharmony_ci 2044f92157deSopenharmony_ciint Add(int val, int& ref, int* ptr) { // NOLINT 2045f92157deSopenharmony_ci int result = val + ref + *ptr; 2046f92157deSopenharmony_ci ref = 42; 2047f92157deSopenharmony_ci *ptr = 43; 2048f92157deSopenharmony_ci return result; 2049f92157deSopenharmony_ci} 2050f92157deSopenharmony_ci 2051f92157deSopenharmony_ciint Deref(std::unique_ptr<int> ptr) { return *ptr; } 2052f92157deSopenharmony_ci 2053f92157deSopenharmony_cistruct Double { 2054f92157deSopenharmony_ci template <typename T> 2055f92157deSopenharmony_ci T operator()(T t) { 2056f92157deSopenharmony_ci return 2 * t; 2057f92157deSopenharmony_ci } 2058f92157deSopenharmony_ci}; 2059f92157deSopenharmony_ci 2060f92157deSopenharmony_cistd::unique_ptr<int> UniqueInt(int i) { 2061f92157deSopenharmony_ci return std::unique_ptr<int>(new int(i)); 2062f92157deSopenharmony_ci} 2063f92157deSopenharmony_ci 2064f92157deSopenharmony_ciTEST(FunctorActionTest, ActionFromFunction) { 2065f92157deSopenharmony_ci Action<int(int, int&, int*)> a = &Add; 2066f92157deSopenharmony_ci int x = 1, y = 2, z = 3; 2067f92157deSopenharmony_ci EXPECT_EQ(6, a.Perform(std::forward_as_tuple(x, y, &z))); 2068f92157deSopenharmony_ci EXPECT_EQ(42, y); 2069f92157deSopenharmony_ci EXPECT_EQ(43, z); 2070f92157deSopenharmony_ci 2071f92157deSopenharmony_ci Action<int(std::unique_ptr<int>)> a1 = &Deref; 2072f92157deSopenharmony_ci EXPECT_EQ(7, a1.Perform(std::make_tuple(UniqueInt(7)))); 2073f92157deSopenharmony_ci} 2074f92157deSopenharmony_ci 2075f92157deSopenharmony_ciTEST(FunctorActionTest, ActionFromLambda) { 2076f92157deSopenharmony_ci Action<int(bool, int)> a1 = [](bool b, int i) { return b ? i : 0; }; 2077f92157deSopenharmony_ci EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5))); 2078f92157deSopenharmony_ci EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 5))); 2079f92157deSopenharmony_ci 2080f92157deSopenharmony_ci std::unique_ptr<int> saved; 2081f92157deSopenharmony_ci Action<void(std::unique_ptr<int>)> a2 = [&saved](std::unique_ptr<int> p) { 2082f92157deSopenharmony_ci saved = std::move(p); 2083f92157deSopenharmony_ci }; 2084f92157deSopenharmony_ci a2.Perform(std::make_tuple(UniqueInt(5))); 2085f92157deSopenharmony_ci EXPECT_EQ(5, *saved); 2086f92157deSopenharmony_ci} 2087f92157deSopenharmony_ci 2088f92157deSopenharmony_ciTEST(FunctorActionTest, PolymorphicFunctor) { 2089f92157deSopenharmony_ci Action<int(int)> ai = Double(); 2090f92157deSopenharmony_ci EXPECT_EQ(2, ai.Perform(std::make_tuple(1))); 2091f92157deSopenharmony_ci Action<double(double)> ad = Double(); // Double? Double double! 2092f92157deSopenharmony_ci EXPECT_EQ(3.0, ad.Perform(std::make_tuple(1.5))); 2093f92157deSopenharmony_ci} 2094f92157deSopenharmony_ci 2095f92157deSopenharmony_ciTEST(FunctorActionTest, TypeConversion) { 2096f92157deSopenharmony_ci // Numeric promotions are allowed. 2097f92157deSopenharmony_ci const Action<bool(int)> a1 = [](int i) { return i > 1; }; 2098f92157deSopenharmony_ci const Action<int(bool)> a2 = Action<int(bool)>(a1); 2099f92157deSopenharmony_ci EXPECT_EQ(1, a1.Perform(std::make_tuple(42))); 2100f92157deSopenharmony_ci EXPECT_EQ(0, a2.Perform(std::make_tuple(42))); 2101f92157deSopenharmony_ci 2102f92157deSopenharmony_ci // Implicit constructors are allowed. 2103f92157deSopenharmony_ci const Action<bool(std::string)> s1 = [](std::string s) { return !s.empty(); }; 2104f92157deSopenharmony_ci const Action<int(const char*)> s2 = Action<int(const char*)>(s1); 2105f92157deSopenharmony_ci EXPECT_EQ(0, s2.Perform(std::make_tuple(""))); 2106f92157deSopenharmony_ci EXPECT_EQ(1, s2.Perform(std::make_tuple("hello"))); 2107f92157deSopenharmony_ci 2108f92157deSopenharmony_ci // Also between the lambda and the action itself. 2109f92157deSopenharmony_ci const Action<bool(std::string)> x1 = [](Unused) { return 42; }; 2110f92157deSopenharmony_ci const Action<bool(std::string)> x2 = [] { return 42; }; 2111f92157deSopenharmony_ci EXPECT_TRUE(x1.Perform(std::make_tuple("hello"))); 2112f92157deSopenharmony_ci EXPECT_TRUE(x2.Perform(std::make_tuple("hello"))); 2113f92157deSopenharmony_ci 2114f92157deSopenharmony_ci // Ensure decay occurs where required. 2115f92157deSopenharmony_ci std::function<int()> f = [] { return 7; }; 2116f92157deSopenharmony_ci Action<int(int)> d = f; 2117f92157deSopenharmony_ci f = nullptr; 2118f92157deSopenharmony_ci EXPECT_EQ(7, d.Perform(std::make_tuple(1))); 2119f92157deSopenharmony_ci 2120f92157deSopenharmony_ci // Ensure creation of an empty action succeeds. 2121f92157deSopenharmony_ci Action<void(int)>(nullptr); 2122f92157deSopenharmony_ci} 2123f92157deSopenharmony_ci 2124f92157deSopenharmony_ciTEST(FunctorActionTest, UnusedArguments) { 2125f92157deSopenharmony_ci // Verify that users can ignore uninteresting arguments. 2126f92157deSopenharmony_ci Action<int(int, double y, double z)> a = [](int i, Unused, Unused) { 2127f92157deSopenharmony_ci return 2 * i; 2128f92157deSopenharmony_ci }; 2129f92157deSopenharmony_ci std::tuple<int, double, double> dummy = std::make_tuple(3, 7.3, 9.44); 2130f92157deSopenharmony_ci EXPECT_EQ(6, a.Perform(dummy)); 2131f92157deSopenharmony_ci} 2132f92157deSopenharmony_ci 2133f92157deSopenharmony_ci// Test that basic built-in actions work with move-only arguments. 2134f92157deSopenharmony_ciTEST(MoveOnlyArgumentsTest, ReturningActions) { 2135f92157deSopenharmony_ci Action<int(std::unique_ptr<int>)> a = Return(1); 2136f92157deSopenharmony_ci EXPECT_EQ(1, a.Perform(std::make_tuple(nullptr))); 2137f92157deSopenharmony_ci 2138f92157deSopenharmony_ci a = testing::WithoutArgs([]() { return 7; }); 2139f92157deSopenharmony_ci EXPECT_EQ(7, a.Perform(std::make_tuple(nullptr))); 2140f92157deSopenharmony_ci 2141f92157deSopenharmony_ci Action<void(std::unique_ptr<int>, int*)> a2 = testing::SetArgPointee<1>(3); 2142f92157deSopenharmony_ci int x = 0; 2143f92157deSopenharmony_ci a2.Perform(std::make_tuple(nullptr, &x)); 2144f92157deSopenharmony_ci EXPECT_EQ(x, 3); 2145f92157deSopenharmony_ci} 2146f92157deSopenharmony_ci 2147f92157deSopenharmony_ciACTION(ReturnArity) { return std::tuple_size<args_type>::value; } 2148f92157deSopenharmony_ci 2149f92157deSopenharmony_ciTEST(ActionMacro, LargeArity) { 2150f92157deSopenharmony_ci EXPECT_EQ( 2151f92157deSopenharmony_ci 1, testing::Action<int(int)>(ReturnArity()).Perform(std::make_tuple(0))); 2152f92157deSopenharmony_ci EXPECT_EQ( 2153f92157deSopenharmony_ci 10, 2154f92157deSopenharmony_ci testing::Action<int(int, int, int, int, int, int, int, int, int, int)>( 2155f92157deSopenharmony_ci ReturnArity()) 2156f92157deSopenharmony_ci .Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); 2157f92157deSopenharmony_ci EXPECT_EQ( 2158f92157deSopenharmony_ci 20, 2159f92157deSopenharmony_ci testing::Action<int(int, int, int, int, int, int, int, int, int, int, int, 2160f92157deSopenharmony_ci int, int, int, int, int, int, int, int, int)>( 2161f92157deSopenharmony_ci ReturnArity()) 2162f92157deSopenharmony_ci .Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 2163f92157deSopenharmony_ci 14, 15, 16, 17, 18, 19))); 2164f92157deSopenharmony_ci} 2165f92157deSopenharmony_ci 2166f92157deSopenharmony_ci} // namespace 2167f92157deSopenharmony_ci} // namespace testing 2168