Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F90936450
gmock-actions_test.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Nov 6, 04:44
Size
47 KB
Mime Type
text/x-c
Expires
Fri, Nov 8, 04:44 (2 d)
Engine
blob
Format
Raw Data
Handle
22163006
Attached To
R9482 SP4E_Homework_Ashtari_Sieber
gmock-actions_test.cc
View Options
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the built-in actions.
// Silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15
#ifdef _MSC_VER
#if _MSC_VER == 1900
# pragma warning(push)
# pragma warning(disable:4800)
#endif
#endif
#include "gmock/gmock-actions.h"
#include <algorithm>
#include <iterator>
#include <memory>
#include <string>
#include <type_traits>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
namespace
{
// This list should be kept sorted.
using
testing
::
_
;
using
testing
::
Action
;
using
testing
::
ActionInterface
;
using
testing
::
Assign
;
using
testing
::
ByMove
;
using
testing
::
ByRef
;
using
testing
::
DefaultValue
;
using
testing
::
DoAll
;
using
testing
::
DoDefault
;
using
testing
::
IgnoreResult
;
using
testing
::
Invoke
;
using
testing
::
InvokeWithoutArgs
;
using
testing
::
MakePolymorphicAction
;
using
testing
::
Ne
;
using
testing
::
PolymorphicAction
;
using
testing
::
Return
;
using
testing
::
ReturnNull
;
using
testing
::
ReturnRef
;
using
testing
::
ReturnRefOfCopy
;
using
testing
::
ReturnRoundRobin
;
using
testing
::
SetArgPointee
;
using
testing
::
SetArgumentPointee
;
using
testing
::
Unused
;
using
testing
::
WithArgs
;
using
testing
::
internal
::
BuiltInDefaultValue
;
using
testing
::
internal
::
Int64
;
using
testing
::
internal
::
UInt64
;
#if !GTEST_OS_WINDOWS_MOBILE
using
testing
::
SetErrnoAndReturn
;
#endif
// Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
TEST
(
BuiltInDefaultValueTest
,
IsNullForPointerTypes
)
{
EXPECT_TRUE
(
BuiltInDefaultValue
<
int
*>::
Get
()
==
nullptr
);
EXPECT_TRUE
(
BuiltInDefaultValue
<
const
char
*>::
Get
()
==
nullptr
);
EXPECT_TRUE
(
BuiltInDefaultValue
<
void
*>::
Get
()
==
nullptr
);
}
// Tests that BuiltInDefaultValue<T*>::Exists() return true.
TEST
(
BuiltInDefaultValueTest
,
ExistsForPointerTypes
)
{
EXPECT_TRUE
(
BuiltInDefaultValue
<
int
*>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
const
char
*>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
void
*>::
Exists
());
}
// Tests that BuiltInDefaultValue<T>::Get() returns 0 when T is a
// built-in numeric type.
TEST
(
BuiltInDefaultValueTest
,
IsZeroForNumericTypes
)
{
EXPECT_EQ
(
0U
,
BuiltInDefaultValue
<
unsigned
char
>::
Get
());
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
signed
char
>::
Get
());
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
char
>::
Get
());
#if GMOCK_WCHAR_T_IS_NATIVE_
#if !defined(__WCHAR_UNSIGNED__)
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
wchar_t
>::
Get
());
#else
EXPECT_EQ
(
0U
,
BuiltInDefaultValue
<
wchar_t
>::
Get
());
#endif
#endif
EXPECT_EQ
(
0U
,
BuiltInDefaultValue
<
unsigned
short
>::
Get
());
// NOLINT
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
signed
short
>::
Get
());
// NOLINT
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
short
>::
Get
());
// NOLINT
EXPECT_EQ
(
0U
,
BuiltInDefaultValue
<
unsigned
int
>::
Get
());
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
signed
int
>::
Get
());
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
int
>::
Get
());
EXPECT_EQ
(
0U
,
BuiltInDefaultValue
<
unsigned
long
>::
Get
());
// NOLINT
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
signed
long
>::
Get
());
// NOLINT
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
long
>::
Get
());
// NOLINT
EXPECT_EQ
(
0U
,
BuiltInDefaultValue
<
UInt64
>::
Get
());
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
Int64
>::
Get
());
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
float
>::
Get
());
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
double
>::
Get
());
}
// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a
// built-in numeric type.
TEST
(
BuiltInDefaultValueTest
,
ExistsForNumericTypes
)
{
EXPECT_TRUE
(
BuiltInDefaultValue
<
unsigned
char
>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
signed
char
>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
char
>::
Exists
());
#if GMOCK_WCHAR_T_IS_NATIVE_
EXPECT_TRUE
(
BuiltInDefaultValue
<
wchar_t
>::
Exists
());
#endif
EXPECT_TRUE
(
BuiltInDefaultValue
<
unsigned
short
>::
Exists
());
// NOLINT
EXPECT_TRUE
(
BuiltInDefaultValue
<
signed
short
>::
Exists
());
// NOLINT
EXPECT_TRUE
(
BuiltInDefaultValue
<
short
>::
Exists
());
// NOLINT
EXPECT_TRUE
(
BuiltInDefaultValue
<
unsigned
int
>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
signed
int
>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
int
>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
unsigned
long
>::
Exists
());
// NOLINT
EXPECT_TRUE
(
BuiltInDefaultValue
<
signed
long
>::
Exists
());
// NOLINT
EXPECT_TRUE
(
BuiltInDefaultValue
<
long
>::
Exists
());
// NOLINT
EXPECT_TRUE
(
BuiltInDefaultValue
<
UInt64
>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
Int64
>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
float
>::
Exists
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
double
>::
Exists
());
}
// Tests that BuiltInDefaultValue<bool>::Get() returns false.
TEST
(
BuiltInDefaultValueTest
,
IsFalseForBool
)
{
EXPECT_FALSE
(
BuiltInDefaultValue
<
bool
>::
Get
());
}
// Tests that BuiltInDefaultValue<bool>::Exists() returns true.
TEST
(
BuiltInDefaultValueTest
,
BoolExists
)
{
EXPECT_TRUE
(
BuiltInDefaultValue
<
bool
>::
Exists
());
}
// Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a
// string type.
TEST
(
BuiltInDefaultValueTest
,
IsEmptyStringForString
)
{
EXPECT_EQ
(
""
,
BuiltInDefaultValue
<
::
std
::
string
>::
Get
());
}
// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a
// string type.
TEST
(
BuiltInDefaultValueTest
,
ExistsForString
)
{
EXPECT_TRUE
(
BuiltInDefaultValue
<
::
std
::
string
>::
Exists
());
}
// Tests that BuiltInDefaultValue<const T>::Get() returns the same
// value as BuiltInDefaultValue<T>::Get() does.
TEST
(
BuiltInDefaultValueTest
,
WorksForConstTypes
)
{
EXPECT_EQ
(
""
,
BuiltInDefaultValue
<
const
std
::
string
>::
Get
());
EXPECT_EQ
(
0
,
BuiltInDefaultValue
<
const
int
>::
Get
());
EXPECT_TRUE
(
BuiltInDefaultValue
<
char
*
const
>::
Get
()
==
nullptr
);
EXPECT_FALSE
(
BuiltInDefaultValue
<
const
bool
>::
Get
());
}
// A type that's default constructible.
class
MyDefaultConstructible
{
public
:
MyDefaultConstructible
()
:
value_
(
42
)
{}
int
value
()
const
{
return
value_
;
}
private
:
int
value_
;
};
// A type that's not default constructible.
class
MyNonDefaultConstructible
{
public
:
// Does not have a default ctor.
explicit
MyNonDefaultConstructible
(
int
a_value
)
:
value_
(
a_value
)
{}
int
value
()
const
{
return
value_
;
}
private
:
int
value_
;
};
TEST
(
BuiltInDefaultValueTest
,
ExistsForDefaultConstructibleType
)
{
EXPECT_TRUE
(
BuiltInDefaultValue
<
MyDefaultConstructible
>::
Exists
());
}
TEST
(
BuiltInDefaultValueTest
,
IsDefaultConstructedForDefaultConstructibleType
)
{
EXPECT_EQ
(
42
,
BuiltInDefaultValue
<
MyDefaultConstructible
>::
Get
().
value
());
}
TEST
(
BuiltInDefaultValueTest
,
DoesNotExistForNonDefaultConstructibleType
)
{
EXPECT_FALSE
(
BuiltInDefaultValue
<
MyNonDefaultConstructible
>::
Exists
());
}
// Tests that BuiltInDefaultValue<T&>::Get() aborts the program.
TEST
(
BuiltInDefaultValueDeathTest
,
IsUndefinedForReferences
)
{
EXPECT_DEATH_IF_SUPPORTED
({
BuiltInDefaultValue
<
int
&>::
Get
();
},
""
);
EXPECT_DEATH_IF_SUPPORTED
({
BuiltInDefaultValue
<
const
char
&>::
Get
();
},
""
);
}
TEST
(
BuiltInDefaultValueDeathTest
,
IsUndefinedForNonDefaultConstructibleType
)
{
EXPECT_DEATH_IF_SUPPORTED
({
BuiltInDefaultValue
<
MyNonDefaultConstructible
>::
Get
();
},
""
);
}
// Tests that DefaultValue<T>::IsSet() is false initially.
TEST
(
DefaultValueTest
,
IsInitiallyUnset
)
{
EXPECT_FALSE
(
DefaultValue
<
int
>::
IsSet
());
EXPECT_FALSE
(
DefaultValue
<
MyDefaultConstructible
>::
IsSet
());
EXPECT_FALSE
(
DefaultValue
<
const
MyNonDefaultConstructible
>::
IsSet
());
}
// Tests that DefaultValue<T> can be set and then unset.
TEST
(
DefaultValueTest
,
CanBeSetAndUnset
)
{
EXPECT_TRUE
(
DefaultValue
<
int
>::
Exists
());
EXPECT_FALSE
(
DefaultValue
<
const
MyNonDefaultConstructible
>::
Exists
());
DefaultValue
<
int
>::
Set
(
1
);
DefaultValue
<
const
MyNonDefaultConstructible
>::
Set
(
MyNonDefaultConstructible
(
42
));
EXPECT_EQ
(
1
,
DefaultValue
<
int
>::
Get
());
EXPECT_EQ
(
42
,
DefaultValue
<
const
MyNonDefaultConstructible
>::
Get
().
value
());
EXPECT_TRUE
(
DefaultValue
<
int
>::
Exists
());
EXPECT_TRUE
(
DefaultValue
<
const
MyNonDefaultConstructible
>::
Exists
());
DefaultValue
<
int
>::
Clear
();
DefaultValue
<
const
MyNonDefaultConstructible
>::
Clear
();
EXPECT_FALSE
(
DefaultValue
<
int
>::
IsSet
());
EXPECT_FALSE
(
DefaultValue
<
const
MyNonDefaultConstructible
>::
IsSet
());
EXPECT_TRUE
(
DefaultValue
<
int
>::
Exists
());
EXPECT_FALSE
(
DefaultValue
<
const
MyNonDefaultConstructible
>::
Exists
());
}
// Tests that DefaultValue<T>::Get() returns the
// BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is
// false.
TEST
(
DefaultValueDeathTest
,
GetReturnsBuiltInDefaultValueWhenUnset
)
{
EXPECT_FALSE
(
DefaultValue
<
int
>::
IsSet
());
EXPECT_TRUE
(
DefaultValue
<
int
>::
Exists
());
EXPECT_FALSE
(
DefaultValue
<
MyNonDefaultConstructible
>::
IsSet
());
EXPECT_FALSE
(
DefaultValue
<
MyNonDefaultConstructible
>::
Exists
());
EXPECT_EQ
(
0
,
DefaultValue
<
int
>::
Get
());
EXPECT_DEATH_IF_SUPPORTED
({
DefaultValue
<
MyNonDefaultConstructible
>::
Get
();
},
""
);
}
TEST
(
DefaultValueTest
,
GetWorksForMoveOnlyIfSet
)
{
EXPECT_TRUE
(
DefaultValue
<
std
::
unique_ptr
<
int
>>::
Exists
());
EXPECT_TRUE
(
DefaultValue
<
std
::
unique_ptr
<
int
>>::
Get
()
==
nullptr
);
DefaultValue
<
std
::
unique_ptr
<
int
>>::
SetFactory
([]
{
return
std
::
unique_ptr
<
int
>
(
new
int
(
42
));
});
EXPECT_TRUE
(
DefaultValue
<
std
::
unique_ptr
<
int
>>::
Exists
());
std
::
unique_ptr
<
int
>
i
=
DefaultValue
<
std
::
unique_ptr
<
int
>>::
Get
();
EXPECT_EQ
(
42
,
*
i
);
}
// Tests that DefaultValue<void>::Get() returns void.
TEST
(
DefaultValueTest
,
GetWorksForVoid
)
{
return
DefaultValue
<
void
>::
Get
();
}
// Tests using DefaultValue with a reference type.
// Tests that DefaultValue<T&>::IsSet() is false initially.
TEST
(
DefaultValueOfReferenceTest
,
IsInitiallyUnset
)
{
EXPECT_FALSE
(
DefaultValue
<
int
&>::
IsSet
());
EXPECT_FALSE
(
DefaultValue
<
MyDefaultConstructible
&>::
IsSet
());
EXPECT_FALSE
(
DefaultValue
<
MyNonDefaultConstructible
&>::
IsSet
());
}
// Tests that DefaultValue<T&>::Exists is false initiallly.
TEST
(
DefaultValueOfReferenceTest
,
IsInitiallyNotExisting
)
{
EXPECT_FALSE
(
DefaultValue
<
int
&>::
Exists
());
EXPECT_FALSE
(
DefaultValue
<
MyDefaultConstructible
&>::
Exists
());
EXPECT_FALSE
(
DefaultValue
<
MyNonDefaultConstructible
&>::
Exists
());
}
// Tests that DefaultValue<T&> can be set and then unset.
TEST
(
DefaultValueOfReferenceTest
,
CanBeSetAndUnset
)
{
int
n
=
1
;
DefaultValue
<
const
int
&>::
Set
(
n
);
MyNonDefaultConstructible
x
(
42
);
DefaultValue
<
MyNonDefaultConstructible
&>::
Set
(
x
);
EXPECT_TRUE
(
DefaultValue
<
const
int
&>::
Exists
());
EXPECT_TRUE
(
DefaultValue
<
MyNonDefaultConstructible
&>::
Exists
());
EXPECT_EQ
(
&
n
,
&
(
DefaultValue
<
const
int
&>::
Get
()));
EXPECT_EQ
(
&
x
,
&
(
DefaultValue
<
MyNonDefaultConstructible
&>::
Get
()));
DefaultValue
<
const
int
&>::
Clear
();
DefaultValue
<
MyNonDefaultConstructible
&>::
Clear
();
EXPECT_FALSE
(
DefaultValue
<
const
int
&>::
Exists
());
EXPECT_FALSE
(
DefaultValue
<
MyNonDefaultConstructible
&>::
Exists
());
EXPECT_FALSE
(
DefaultValue
<
const
int
&>::
IsSet
());
EXPECT_FALSE
(
DefaultValue
<
MyNonDefaultConstructible
&>::
IsSet
());
}
// Tests that DefaultValue<T&>::Get() returns the
// BuiltInDefaultValue<T&>::Get() when DefaultValue<T&>::IsSet() is
// false.
TEST
(
DefaultValueOfReferenceDeathTest
,
GetReturnsBuiltInDefaultValueWhenUnset
)
{
EXPECT_FALSE
(
DefaultValue
<
int
&>::
IsSet
());
EXPECT_FALSE
(
DefaultValue
<
MyNonDefaultConstructible
&>::
IsSet
());
EXPECT_DEATH_IF_SUPPORTED
({
DefaultValue
<
int
&>::
Get
();
},
""
);
EXPECT_DEATH_IF_SUPPORTED
({
DefaultValue
<
MyNonDefaultConstructible
>::
Get
();
},
""
);
}
// Tests that ActionInterface can be implemented by defining the
// Perform method.
typedef
int
MyGlobalFunction
(
bool
,
int
);
class
MyActionImpl
:
public
ActionInterface
<
MyGlobalFunction
>
{
public
:
int
Perform
(
const
std
::
tuple
<
bool
,
int
>&
args
)
override
{
return
std
::
get
<
0
>
(
args
)
?
std
::
get
<
1
>
(
args
)
:
0
;
}
};
TEST
(
ActionInterfaceTest
,
CanBeImplementedByDefiningPerform
)
{
MyActionImpl
my_action_impl
;
(
void
)
my_action_impl
;
}
TEST
(
ActionInterfaceTest
,
MakeAction
)
{
Action
<
MyGlobalFunction
>
action
=
MakeAction
(
new
MyActionImpl
);
// When exercising the Perform() method of Action<F>, we must pass
// it a tuple whose size and type are compatible with F's argument
// types. For example, if F is int(), then Perform() takes a
// 0-tuple; if F is void(bool, int), then Perform() takes a
// std::tuple<bool, int>, and so on.
EXPECT_EQ
(
5
,
action
.
Perform
(
std
::
make_tuple
(
true
,
5
)));
}
// Tests that Action<F> can be contructed from a pointer to
// ActionInterface<F>.
TEST
(
ActionTest
,
CanBeConstructedFromActionInterface
)
{
Action
<
MyGlobalFunction
>
action
(
new
MyActionImpl
);
}
// Tests that Action<F> delegates actual work to ActionInterface<F>.
TEST
(
ActionTest
,
DelegatesWorkToActionInterface
)
{
const
Action
<
MyGlobalFunction
>
action
(
new
MyActionImpl
);
EXPECT_EQ
(
5
,
action
.
Perform
(
std
::
make_tuple
(
true
,
5
)));
EXPECT_EQ
(
0
,
action
.
Perform
(
std
::
make_tuple
(
false
,
1
)));
}
// Tests that Action<F> can be copied.
TEST
(
ActionTest
,
IsCopyable
)
{
Action
<
MyGlobalFunction
>
a1
(
new
MyActionImpl
);
Action
<
MyGlobalFunction
>
a2
(
a1
);
// Tests the copy constructor.
// a1 should continue to work after being copied from.
EXPECT_EQ
(
5
,
a1
.
Perform
(
std
::
make_tuple
(
true
,
5
)));
EXPECT_EQ
(
0
,
a1
.
Perform
(
std
::
make_tuple
(
false
,
1
)));
// a2 should work like the action it was copied from.
EXPECT_EQ
(
5
,
a2
.
Perform
(
std
::
make_tuple
(
true
,
5
)));
EXPECT_EQ
(
0
,
a2
.
Perform
(
std
::
make_tuple
(
false
,
1
)));
a2
=
a1
;
// Tests the assignment operator.
// a1 should continue to work after being copied from.
EXPECT_EQ
(
5
,
a1
.
Perform
(
std
::
make_tuple
(
true
,
5
)));
EXPECT_EQ
(
0
,
a1
.
Perform
(
std
::
make_tuple
(
false
,
1
)));
// a2 should work like the action it was copied from.
EXPECT_EQ
(
5
,
a2
.
Perform
(
std
::
make_tuple
(
true
,
5
)));
EXPECT_EQ
(
0
,
a2
.
Perform
(
std
::
make_tuple
(
false
,
1
)));
}
// Tests that an Action<From> object can be converted to a
// compatible Action<To> object.
class
IsNotZero
:
public
ActionInterface
<
bool
(
int
)
>
{
// NOLINT
public
:
bool
Perform
(
const
std
::
tuple
<
int
>&
arg
)
override
{
return
std
::
get
<
0
>
(
arg
)
!=
0
;
}
};
TEST
(
ActionTest
,
CanBeConvertedToOtherActionType
)
{
const
Action
<
bool
(
int
)
>
a1
(
new
IsNotZero
);
// NOLINT
const
Action
<
int
(
char
)
>
a2
=
Action
<
int
(
char
)
>
(
a1
);
// NOLINT
EXPECT_EQ
(
1
,
a2
.
Perform
(
std
::
make_tuple
(
'a'
)));
EXPECT_EQ
(
0
,
a2
.
Perform
(
std
::
make_tuple
(
'\0'
)));
}
// The following two classes are for testing MakePolymorphicAction().
// Implements a polymorphic action that returns the second of the
// arguments it receives.
class
ReturnSecondArgumentAction
{
public
:
// We want to verify that MakePolymorphicAction() can work with a
// polymorphic action whose Perform() method template is either
// const or not. This lets us verify the non-const case.
template
<
typename
Result
,
typename
ArgumentTuple
>
Result
Perform
(
const
ArgumentTuple
&
args
)
{
return
std
::
get
<
1
>
(
args
);
}
};
// Implements a polymorphic action that can be used in a nullary
// function to return 0.
class
ReturnZeroFromNullaryFunctionAction
{
public
:
// For testing that MakePolymorphicAction() works when the
// implementation class' Perform() method template takes only one
// template parameter.
//
// We want to verify that MakePolymorphicAction() can work with a
// polymorphic action whose Perform() method template is either
// const or not. This lets us verify the const case.
template
<
typename
Result
>
Result
Perform
(
const
std
::
tuple
<>&
)
const
{
return
0
;
}
};
// These functions verify that MakePolymorphicAction() returns a
// PolymorphicAction<T> where T is the argument's type.
PolymorphicAction
<
ReturnSecondArgumentAction
>
ReturnSecondArgument
()
{
return
MakePolymorphicAction
(
ReturnSecondArgumentAction
());
}
PolymorphicAction
<
ReturnZeroFromNullaryFunctionAction
>
ReturnZeroFromNullaryFunction
()
{
return
MakePolymorphicAction
(
ReturnZeroFromNullaryFunctionAction
());
}
// Tests that MakePolymorphicAction() turns a polymorphic action
// implementation class into a polymorphic action.
TEST
(
MakePolymorphicActionTest
,
ConstructsActionFromImpl
)
{
Action
<
int
(
bool
,
int
,
double
)
>
a1
=
ReturnSecondArgument
();
// NOLINT
EXPECT_EQ
(
5
,
a1
.
Perform
(
std
::
make_tuple
(
false
,
5
,
2.0
)));
}
// Tests that MakePolymorphicAction() works when the implementation
// class' Perform() method template has only one template parameter.
TEST
(
MakePolymorphicActionTest
,
WorksWhenPerformHasOneTemplateParameter
)
{
Action
<
int
()
>
a1
=
ReturnZeroFromNullaryFunction
();
EXPECT_EQ
(
0
,
a1
.
Perform
(
std
::
make_tuple
()));
Action
<
void
*
()
>
a2
=
ReturnZeroFromNullaryFunction
();
EXPECT_TRUE
(
a2
.
Perform
(
std
::
make_tuple
())
==
nullptr
);
}
// Tests that Return() works as an action for void-returning
// functions.
TEST
(
ReturnTest
,
WorksForVoid
)
{
const
Action
<
void
(
int
)
>
ret
=
Return
();
// NOLINT
return
ret
.
Perform
(
std
::
make_tuple
(
1
));
}
// Tests that Return(v) returns v.
TEST
(
ReturnTest
,
ReturnsGivenValue
)
{
Action
<
int
()
>
ret
=
Return
(
1
);
// NOLINT
EXPECT_EQ
(
1
,
ret
.
Perform
(
std
::
make_tuple
()));
ret
=
Return
(
-
5
);
EXPECT_EQ
(
-
5
,
ret
.
Perform
(
std
::
make_tuple
()));
}
// Tests that Return("string literal") works.
TEST
(
ReturnTest
,
AcceptsStringLiteral
)
{
Action
<
const
char
*
()
>
a1
=
Return
(
"Hello"
);
EXPECT_STREQ
(
"Hello"
,
a1
.
Perform
(
std
::
make_tuple
()));
Action
<
std
::
string
()
>
a2
=
Return
(
"world"
);
EXPECT_EQ
(
"world"
,
a2
.
Perform
(
std
::
make_tuple
()));
}
// Test struct which wraps a vector of integers. Used in
// 'SupportsWrapperReturnType' test.
struct
IntegerVectorWrapper
{
std
::
vector
<
int
>
*
v
;
IntegerVectorWrapper
(
std
::
vector
<
int
>&
_v
)
:
v
(
&
_v
)
{}
// NOLINT
};
// Tests that Return() works when return type is a wrapper type.
TEST
(
ReturnTest
,
SupportsWrapperReturnType
)
{
// Initialize vector of integers.
std
::
vector
<
int
>
v
;
for
(
int
i
=
0
;
i
<
5
;
++
i
)
v
.
push_back
(
i
);
// Return() called with 'v' as argument. The Action will return the same data
// as 'v' (copy) but it will be wrapped in an IntegerVectorWrapper.
Action
<
IntegerVectorWrapper
()
>
a
=
Return
(
v
);
const
std
::
vector
<
int
>&
result
=
*
(
a
.
Perform
(
std
::
make_tuple
()).
v
);
EXPECT_THAT
(
result
,
::
testing
::
ElementsAre
(
0
,
1
,
2
,
3
,
4
));
}
// Tests that Return(v) is covaraint.
struct
Base
{
bool
operator
==
(
const
Base
&
)
{
return
true
;
}
};
struct
Derived
:
public
Base
{
bool
operator
==
(
const
Derived
&
)
{
return
true
;
}
};
TEST
(
ReturnTest
,
IsCovariant
)
{
Base
base
;
Derived
derived
;
Action
<
Base
*
()
>
ret
=
Return
(
&
base
);
EXPECT_EQ
(
&
base
,
ret
.
Perform
(
std
::
make_tuple
()));
ret
=
Return
(
&
derived
);
EXPECT_EQ
(
&
derived
,
ret
.
Perform
(
std
::
make_tuple
()));
}
// Tests that the type of the value passed into Return is converted into T
// when the action is cast to Action<T(...)> rather than when the action is
// performed. See comments on testing::internal::ReturnAction in
// gmock-actions.h for more information.
class
FromType
{
public
:
explicit
FromType
(
bool
*
is_converted
)
:
converted_
(
is_converted
)
{}
bool
*
converted
()
const
{
return
converted_
;
}
private
:
bool
*
const
converted_
;
GTEST_DISALLOW_ASSIGN_
(
FromType
);
};
class
ToType
{
public
:
// Must allow implicit conversion due to use in ImplicitCast_<T>.
ToType
(
const
FromType
&
x
)
{
*
x
.
converted
()
=
true
;
}
// NOLINT
};
TEST
(
ReturnTest
,
ConvertsArgumentWhenConverted
)
{
bool
converted
=
false
;
FromType
x
(
&
converted
);
Action
<
ToType
()
>
action
(
Return
(
x
));
EXPECT_TRUE
(
converted
)
<<
"Return must convert its argument in its own "
<<
"conversion operator."
;
converted
=
false
;
action
.
Perform
(
std
::
tuple
<>
());
EXPECT_FALSE
(
converted
)
<<
"Action must NOT convert its argument "
<<
"when performed."
;
}
class
DestinationType
{};
class
SourceType
{
public
:
// Note: a non-const typecast operator.
operator
DestinationType
()
{
return
DestinationType
();
}
};
TEST
(
ReturnTest
,
CanConvertArgumentUsingNonConstTypeCastOperator
)
{
SourceType
s
;
Action
<
DestinationType
()
>
action
(
Return
(
s
));
}
// Tests that ReturnNull() returns NULL in a pointer-returning function.
TEST
(
ReturnNullTest
,
WorksInPointerReturningFunction
)
{
const
Action
<
int
*
()
>
a1
=
ReturnNull
();
EXPECT_TRUE
(
a1
.
Perform
(
std
::
make_tuple
())
==
nullptr
);
const
Action
<
const
char
*
(
bool
)
>
a2
=
ReturnNull
();
// NOLINT
EXPECT_TRUE
(
a2
.
Perform
(
std
::
make_tuple
(
true
))
==
nullptr
);
}
// Tests that ReturnNull() returns NULL for shared_ptr and unique_ptr returning
// functions.
TEST
(
ReturnNullTest
,
WorksInSmartPointerReturningFunction
)
{
const
Action
<
std
::
unique_ptr
<
const
int
>
()
>
a1
=
ReturnNull
();
EXPECT_TRUE
(
a1
.
Perform
(
std
::
make_tuple
())
==
nullptr
);
const
Action
<
std
::
shared_ptr
<
int
>
(
std
::
string
)
>
a2
=
ReturnNull
();
EXPECT_TRUE
(
a2
.
Perform
(
std
::
make_tuple
(
"foo"
))
==
nullptr
);
}
// Tests that ReturnRef(v) works for reference types.
TEST
(
ReturnRefTest
,
WorksForReference
)
{
const
int
n
=
0
;
const
Action
<
const
int
&
(
bool
)
>
ret
=
ReturnRef
(
n
);
// NOLINT
EXPECT_EQ
(
&
n
,
&
ret
.
Perform
(
std
::
make_tuple
(
true
)));
}
// Tests that ReturnRef(v) is covariant.
TEST
(
ReturnRefTest
,
IsCovariant
)
{
Base
base
;
Derived
derived
;
Action
<
Base
&
()
>
a
=
ReturnRef
(
base
);
EXPECT_EQ
(
&
base
,
&
a
.
Perform
(
std
::
make_tuple
()));
a
=
ReturnRef
(
derived
);
EXPECT_EQ
(
&
derived
,
&
a
.
Perform
(
std
::
make_tuple
()));
}
template
<
typename
T
,
typename
=
decltype
(
ReturnRef
(
std
::
declval
<
T
&&>
()))
>
bool
CanCallReturnRef
(
T
&&
)
{
return
true
;
}
bool
CanCallReturnRef
(
Unused
)
{
return
false
;
}
// Tests that ReturnRef(v) is working with non-temporaries (T&)
TEST
(
ReturnRefTest
,
WorksForNonTemporary
)
{
int
scalar_value
=
123
;
EXPECT_TRUE
(
CanCallReturnRef
(
scalar_value
));
std
::
string
non_scalar_value
(
"ABC"
);
EXPECT_TRUE
(
CanCallReturnRef
(
non_scalar_value
));
const
int
const_scalar_value
{
321
};
EXPECT_TRUE
(
CanCallReturnRef
(
const_scalar_value
));
const
std
::
string
const_non_scalar_value
(
"CBA"
);
EXPECT_TRUE
(
CanCallReturnRef
(
const_non_scalar_value
));
}
// Tests that ReturnRef(v) is not working with temporaries (T&&)
TEST
(
ReturnRefTest
,
DoesNotWorkForTemporary
)
{
auto
scalar_value
=
[]()
->
int
{
return
123
;
};
EXPECT_FALSE
(
CanCallReturnRef
(
scalar_value
()));
auto
non_scalar_value
=
[]()
->
std
::
string
{
return
"ABC"
;
};
EXPECT_FALSE
(
CanCallReturnRef
(
non_scalar_value
()));
// cannot use here callable returning "const scalar type",
// because such const for scalar return type is ignored
EXPECT_FALSE
(
CanCallReturnRef
(
static_cast
<
const
int
>
(
321
)));
auto
const_non_scalar_value
=
[]()
->
const
std
::
string
{
return
"CBA"
;
};
EXPECT_FALSE
(
CanCallReturnRef
(
const_non_scalar_value
()));
}
// Tests that ReturnRefOfCopy(v) works for reference types.
TEST
(
ReturnRefOfCopyTest
,
WorksForReference
)
{
int
n
=
42
;
const
Action
<
const
int
&
()
>
ret
=
ReturnRefOfCopy
(
n
);
EXPECT_NE
(
&
n
,
&
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
42
,
ret
.
Perform
(
std
::
make_tuple
()));
n
=
43
;
EXPECT_NE
(
&
n
,
&
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
42
,
ret
.
Perform
(
std
::
make_tuple
()));
}
// Tests that ReturnRefOfCopy(v) is covariant.
TEST
(
ReturnRefOfCopyTest
,
IsCovariant
)
{
Base
base
;
Derived
derived
;
Action
<
Base
&
()
>
a
=
ReturnRefOfCopy
(
base
);
EXPECT_NE
(
&
base
,
&
a
.
Perform
(
std
::
make_tuple
()));
a
=
ReturnRefOfCopy
(
derived
);
EXPECT_NE
(
&
derived
,
&
a
.
Perform
(
std
::
make_tuple
()));
}
// Tests that ReturnRoundRobin(v) works with initializer lists
TEST
(
ReturnRoundRobinTest
,
WorksForInitList
)
{
Action
<
int
()
>
ret
=
ReturnRoundRobin
({
1
,
2
,
3
});
EXPECT_EQ
(
1
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
2
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
3
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
1
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
2
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
3
,
ret
.
Perform
(
std
::
make_tuple
()));
}
// Tests that ReturnRoundRobin(v) works with vectors
TEST
(
ReturnRoundRobinTest
,
WorksForVector
)
{
std
::
vector
<
double
>
v
=
{
4.4
,
5.5
,
6.6
};
Action
<
double
()
>
ret
=
ReturnRoundRobin
(
v
);
EXPECT_EQ
(
4.4
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
5.5
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
6.6
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
4.4
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
5.5
,
ret
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
6.6
,
ret
.
Perform
(
std
::
make_tuple
()));
}
// Tests that DoDefault() does the default action for the mock method.
class
MockClass
{
public
:
MockClass
()
{}
MOCK_METHOD1
(
IntFunc
,
int
(
bool
flag
));
// NOLINT
MOCK_METHOD0
(
Foo
,
MyNonDefaultConstructible
());
MOCK_METHOD0
(
MakeUnique
,
std
::
unique_ptr
<
int
>
());
MOCK_METHOD0
(
MakeUniqueBase
,
std
::
unique_ptr
<
Base
>
());
MOCK_METHOD0
(
MakeVectorUnique
,
std
::
vector
<
std
::
unique_ptr
<
int
>>
());
MOCK_METHOD1
(
TakeUnique
,
int
(
std
::
unique_ptr
<
int
>
));
MOCK_METHOD2
(
TakeUnique
,
int
(
const
std
::
unique_ptr
<
int
>&
,
std
::
unique_ptr
<
int
>
));
private
:
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
MockClass
);
};
// Tests that DoDefault() returns the built-in default value for the
// return type by default.
TEST
(
DoDefaultTest
,
ReturnsBuiltInDefaultValueByDefault
)
{
MockClass
mock
;
EXPECT_CALL
(
mock
,
IntFunc
(
_
))
.
WillOnce
(
DoDefault
());
EXPECT_EQ
(
0
,
mock
.
IntFunc
(
true
));
}
// Tests that DoDefault() throws (when exceptions are enabled) or aborts
// the process when there is no built-in default value for the return type.
TEST
(
DoDefaultDeathTest
,
DiesForUnknowType
)
{
MockClass
mock
;
EXPECT_CALL
(
mock
,
Foo
())
.
WillRepeatedly
(
DoDefault
());
#if GTEST_HAS_EXCEPTIONS
EXPECT_ANY_THROW
(
mock
.
Foo
());
#else
EXPECT_DEATH_IF_SUPPORTED
({
mock
.
Foo
();
},
""
);
#endif
}
// Tests that using DoDefault() inside a composite action leads to a
// run-time error.
void
VoidFunc
(
bool
/* flag */
)
{}
TEST
(
DoDefaultDeathTest
,
DiesIfUsedInCompositeAction
)
{
MockClass
mock
;
EXPECT_CALL
(
mock
,
IntFunc
(
_
))
.
WillRepeatedly
(
DoAll
(
Invoke
(
VoidFunc
),
DoDefault
()));
// Ideally we should verify the error message as well. Sadly,
// EXPECT_DEATH() can only capture stderr, while Google Mock's
// errors are printed on stdout. Therefore we have to settle for
// not verifying the message.
EXPECT_DEATH_IF_SUPPORTED
({
mock
.
IntFunc
(
true
);
},
""
);
}
// Tests that DoDefault() returns the default value set by
// DefaultValue<T>::Set() when it's not overriden by an ON_CALL().
TEST
(
DoDefaultTest
,
ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne
)
{
DefaultValue
<
int
>::
Set
(
1
);
MockClass
mock
;
EXPECT_CALL
(
mock
,
IntFunc
(
_
))
.
WillOnce
(
DoDefault
());
EXPECT_EQ
(
1
,
mock
.
IntFunc
(
false
));
DefaultValue
<
int
>::
Clear
();
}
// Tests that DoDefault() does the action specified by ON_CALL().
TEST
(
DoDefaultTest
,
DoesWhatOnCallSpecifies
)
{
MockClass
mock
;
ON_CALL
(
mock
,
IntFunc
(
_
))
.
WillByDefault
(
Return
(
2
));
EXPECT_CALL
(
mock
,
IntFunc
(
_
))
.
WillOnce
(
DoDefault
());
EXPECT_EQ
(
2
,
mock
.
IntFunc
(
false
));
}
// Tests that using DoDefault() in ON_CALL() leads to a run-time failure.
TEST
(
DoDefaultTest
,
CannotBeUsedInOnCall
)
{
MockClass
mock
;
EXPECT_NONFATAL_FAILURE
({
// NOLINT
ON_CALL
(
mock
,
IntFunc
(
_
))
.
WillByDefault
(
DoDefault
());
},
"DoDefault() cannot be used in ON_CALL()"
);
}
// Tests that SetArgPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v.
TEST
(
SetArgPointeeTest
,
SetsTheNthPointee
)
{
typedef
void
MyFunction
(
bool
,
int
*
,
char
*
);
Action
<
MyFunction
>
a
=
SetArgPointee
<
1
>
(
2
);
int
n
=
0
;
char
ch
=
'\0'
;
a
.
Perform
(
std
::
make_tuple
(
true
,
&
n
,
&
ch
));
EXPECT_EQ
(
2
,
n
);
EXPECT_EQ
(
'\0'
,
ch
);
a
=
SetArgPointee
<
2
>
(
'a'
);
n
=
0
;
ch
=
'\0'
;
a
.
Perform
(
std
::
make_tuple
(
true
,
&
n
,
&
ch
));
EXPECT_EQ
(
0
,
n
);
EXPECT_EQ
(
'a'
,
ch
);
}
// Tests that SetArgPointee<N>() accepts a string literal.
TEST
(
SetArgPointeeTest
,
AcceptsStringLiteral
)
{
typedef
void
MyFunction
(
std
::
string
*
,
const
char
**
);
Action
<
MyFunction
>
a
=
SetArgPointee
<
0
>
(
"hi"
);
std
::
string
str
;
const
char
*
ptr
=
nullptr
;
a
.
Perform
(
std
::
make_tuple
(
&
str
,
&
ptr
));
EXPECT_EQ
(
"hi"
,
str
);
EXPECT_TRUE
(
ptr
==
nullptr
);
a
=
SetArgPointee
<
1
>
(
"world"
);
str
=
""
;
a
.
Perform
(
std
::
make_tuple
(
&
str
,
&
ptr
));
EXPECT_EQ
(
""
,
str
);
EXPECT_STREQ
(
"world"
,
ptr
);
}
TEST
(
SetArgPointeeTest
,
AcceptsWideStringLiteral
)
{
typedef
void
MyFunction
(
const
wchar_t
**
);
Action
<
MyFunction
>
a
=
SetArgPointee
<
0
>
(
L"world"
);
const
wchar_t
*
ptr
=
nullptr
;
a
.
Perform
(
std
::
make_tuple
(
&
ptr
));
EXPECT_STREQ
(
L"world"
,
ptr
);
# if GTEST_HAS_STD_WSTRING
typedef
void
MyStringFunction
(
std
::
wstring
*
);
Action
<
MyStringFunction
>
a2
=
SetArgPointee
<
0
>
(
L"world"
);
std
::
wstring
str
=
L""
;
a2
.
Perform
(
std
::
make_tuple
(
&
str
));
EXPECT_EQ
(
L"world"
,
str
);
# endif
}
// Tests that SetArgPointee<N>() accepts a char pointer.
TEST
(
SetArgPointeeTest
,
AcceptsCharPointer
)
{
typedef
void
MyFunction
(
bool
,
std
::
string
*
,
const
char
**
);
const
char
*
const
hi
=
"hi"
;
Action
<
MyFunction
>
a
=
SetArgPointee
<
1
>
(
hi
);
std
::
string
str
;
const
char
*
ptr
=
nullptr
;
a
.
Perform
(
std
::
make_tuple
(
true
,
&
str
,
&
ptr
));
EXPECT_EQ
(
"hi"
,
str
);
EXPECT_TRUE
(
ptr
==
nullptr
);
char
world_array
[]
=
"world"
;
char
*
const
world
=
world_array
;
a
=
SetArgPointee
<
2
>
(
world
);
str
=
""
;
a
.
Perform
(
std
::
make_tuple
(
true
,
&
str
,
&
ptr
));
EXPECT_EQ
(
""
,
str
);
EXPECT_EQ
(
world
,
ptr
);
}
TEST
(
SetArgPointeeTest
,
AcceptsWideCharPointer
)
{
typedef
void
MyFunction
(
bool
,
const
wchar_t
**
);
const
wchar_t
*
const
hi
=
L"hi"
;
Action
<
MyFunction
>
a
=
SetArgPointee
<
1
>
(
hi
);
const
wchar_t
*
ptr
=
nullptr
;
a
.
Perform
(
std
::
make_tuple
(
true
,
&
ptr
));
EXPECT_EQ
(
hi
,
ptr
);
# if GTEST_HAS_STD_WSTRING
typedef
void
MyStringFunction
(
bool
,
std
::
wstring
*
);
wchar_t
world_array
[]
=
L"world"
;
wchar_t
*
const
world
=
world_array
;
Action
<
MyStringFunction
>
a2
=
SetArgPointee
<
1
>
(
world
);
std
::
wstring
str
;
a2
.
Perform
(
std
::
make_tuple
(
true
,
&
str
));
EXPECT_EQ
(
world_array
,
str
);
# endif
}
// Tests that SetArgumentPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v.
TEST
(
SetArgumentPointeeTest
,
SetsTheNthPointee
)
{
typedef
void
MyFunction
(
bool
,
int
*
,
char
*
);
Action
<
MyFunction
>
a
=
SetArgumentPointee
<
1
>
(
2
);
int
n
=
0
;
char
ch
=
'\0'
;
a
.
Perform
(
std
::
make_tuple
(
true
,
&
n
,
&
ch
));
EXPECT_EQ
(
2
,
n
);
EXPECT_EQ
(
'\0'
,
ch
);
a
=
SetArgumentPointee
<
2
>
(
'a'
);
n
=
0
;
ch
=
'\0'
;
a
.
Perform
(
std
::
make_tuple
(
true
,
&
n
,
&
ch
));
EXPECT_EQ
(
0
,
n
);
EXPECT_EQ
(
'a'
,
ch
);
}
// Sample functions and functors for testing Invoke() and etc.
int
Nullary
()
{
return
1
;
}
class
NullaryFunctor
{
public
:
int
operator
()()
{
return
2
;
}
};
bool
g_done
=
false
;
void
VoidNullary
()
{
g_done
=
true
;
}
class
VoidNullaryFunctor
{
public
:
void
operator
()()
{
g_done
=
true
;
}
};
short
Short
(
short
n
)
{
return
n
;
}
// NOLINT
char
Char
(
char
ch
)
{
return
ch
;
}
const
char
*
CharPtr
(
const
char
*
s
)
{
return
s
;
}
bool
Unary
(
int
x
)
{
return
x
<
0
;
}
const
char
*
Binary
(
const
char
*
input
,
short
n
)
{
return
input
+
n
;
}
// NOLINT
void
VoidBinary
(
int
,
char
)
{
g_done
=
true
;
}
int
Ternary
(
int
x
,
char
y
,
short
z
)
{
return
x
+
y
+
z
;
}
// NOLINT
int
SumOf4
(
int
a
,
int
b
,
int
c
,
int
d
)
{
return
a
+
b
+
c
+
d
;
}
class
Foo
{
public
:
Foo
()
:
value_
(
123
)
{}
int
Nullary
()
const
{
return
value_
;
}
private
:
int
value_
;
};
// Tests InvokeWithoutArgs(function).
TEST
(
InvokeWithoutArgsTest
,
Function
)
{
// As an action that takes one argument.
Action
<
int
(
int
)
>
a
=
InvokeWithoutArgs
(
Nullary
);
// NOLINT
EXPECT_EQ
(
1
,
a
.
Perform
(
std
::
make_tuple
(
2
)));
// As an action that takes two arguments.
Action
<
int
(
int
,
double
)
>
a2
=
InvokeWithoutArgs
(
Nullary
);
// NOLINT
EXPECT_EQ
(
1
,
a2
.
Perform
(
std
::
make_tuple
(
2
,
3.5
)));
// As an action that returns void.
Action
<
void
(
int
)
>
a3
=
InvokeWithoutArgs
(
VoidNullary
);
// NOLINT
g_done
=
false
;
a3
.
Perform
(
std
::
make_tuple
(
1
));
EXPECT_TRUE
(
g_done
);
}
// Tests InvokeWithoutArgs(functor).
TEST
(
InvokeWithoutArgsTest
,
Functor
)
{
// As an action that takes no argument.
Action
<
int
()
>
a
=
InvokeWithoutArgs
(
NullaryFunctor
());
// NOLINT
EXPECT_EQ
(
2
,
a
.
Perform
(
std
::
make_tuple
()));
// As an action that takes three arguments.
Action
<
int
(
int
,
double
,
char
)
>
a2
=
// NOLINT
InvokeWithoutArgs
(
NullaryFunctor
());
EXPECT_EQ
(
2
,
a2
.
Perform
(
std
::
make_tuple
(
3
,
3.5
,
'a'
)));
// As an action that returns void.
Action
<
void
()
>
a3
=
InvokeWithoutArgs
(
VoidNullaryFunctor
());
g_done
=
false
;
a3
.
Perform
(
std
::
make_tuple
());
EXPECT_TRUE
(
g_done
);
}
// Tests InvokeWithoutArgs(obj_ptr, method).
TEST
(
InvokeWithoutArgsTest
,
Method
)
{
Foo
foo
;
Action
<
int
(
bool
,
char
)
>
a
=
// NOLINT
InvokeWithoutArgs
(
&
foo
,
&
Foo
::
Nullary
);
EXPECT_EQ
(
123
,
a
.
Perform
(
std
::
make_tuple
(
true
,
'a'
)));
}
// Tests using IgnoreResult() on a polymorphic action.
TEST
(
IgnoreResultTest
,
PolymorphicAction
)
{
Action
<
void
(
int
)
>
a
=
IgnoreResult
(
Return
(
5
));
// NOLINT
a
.
Perform
(
std
::
make_tuple
(
1
));
}
// Tests using IgnoreResult() on a monomorphic action.
int
ReturnOne
()
{
g_done
=
true
;
return
1
;
}
TEST
(
IgnoreResultTest
,
MonomorphicAction
)
{
g_done
=
false
;
Action
<
void
()
>
a
=
IgnoreResult
(
Invoke
(
ReturnOne
));
a
.
Perform
(
std
::
make_tuple
());
EXPECT_TRUE
(
g_done
);
}
// Tests using IgnoreResult() on an action that returns a class type.
MyNonDefaultConstructible
ReturnMyNonDefaultConstructible
(
double
/* x */
)
{
g_done
=
true
;
return
MyNonDefaultConstructible
(
42
);
}
TEST
(
IgnoreResultTest
,
ActionReturningClass
)
{
g_done
=
false
;
Action
<
void
(
int
)
>
a
=
IgnoreResult
(
Invoke
(
ReturnMyNonDefaultConstructible
));
// NOLINT
a
.
Perform
(
std
::
make_tuple
(
2
));
EXPECT_TRUE
(
g_done
);
}
TEST
(
AssignTest
,
Int
)
{
int
x
=
0
;
Action
<
void
(
int
)
>
a
=
Assign
(
&
x
,
5
);
a
.
Perform
(
std
::
make_tuple
(
0
));
EXPECT_EQ
(
5
,
x
);
}
TEST
(
AssignTest
,
String
)
{
::
std
::
string
x
;
Action
<
void
(
void
)
>
a
=
Assign
(
&
x
,
"Hello, world"
);
a
.
Perform
(
std
::
make_tuple
());
EXPECT_EQ
(
"Hello, world"
,
x
);
}
TEST
(
AssignTest
,
CompatibleTypes
)
{
double
x
=
0
;
Action
<
void
(
int
)
>
a
=
Assign
(
&
x
,
5
);
a
.
Perform
(
std
::
make_tuple
(
0
));
EXPECT_DOUBLE_EQ
(
5
,
x
);
}
// Tests using WithArgs and with an action that takes 1 argument.
TEST
(
WithArgsTest
,
OneArg
)
{
Action
<
bool
(
double
x
,
int
n
)
>
a
=
WithArgs
<
1
>
(
Invoke
(
Unary
));
// NOLINT
EXPECT_TRUE
(
a
.
Perform
(
std
::
make_tuple
(
1.5
,
-
1
)));
EXPECT_FALSE
(
a
.
Perform
(
std
::
make_tuple
(
1.5
,
1
)));
}
// Tests using WithArgs with an action that takes 2 arguments.
TEST
(
WithArgsTest
,
TwoArgs
)
{
Action
<
const
char
*
(
const
char
*
s
,
double
x
,
short
n
)
>
a
=
// NOLINT
WithArgs
<
0
,
2
>
(
Invoke
(
Binary
));
const
char
s
[]
=
"Hello"
;
EXPECT_EQ
(
s
+
2
,
a
.
Perform
(
std
::
make_tuple
(
CharPtr
(
s
),
0.5
,
Short
(
2
))));
}
struct
ConcatAll
{
std
::
string
operator
()()
const
{
return
{};
}
template
<
typename
...
I
>
std
::
string
operator
()(
const
char
*
a
,
I
...
i
)
const
{
return
a
+
ConcatAll
()(
i
...);
}
};
// Tests using WithArgs with an action that takes 10 arguments.
TEST
(
WithArgsTest
,
TenArgs
)
{
Action
<
std
::
string
(
const
char
*
,
const
char
*
,
const
char
*
,
const
char
*
)
>
a
=
WithArgs
<
0
,
1
,
2
,
3
,
2
,
1
,
0
,
1
,
2
,
3
>
(
Invoke
(
ConcatAll
{}));
EXPECT_EQ
(
"0123210123"
,
a
.
Perform
(
std
::
make_tuple
(
CharPtr
(
"0"
),
CharPtr
(
"1"
),
CharPtr
(
"2"
),
CharPtr
(
"3"
))));
}
// Tests using WithArgs with an action that is not Invoke().
class
SubtractAction
:
public
ActionInterface
<
int
(
int
,
int
)
>
{
public
:
int
Perform
(
const
std
::
tuple
<
int
,
int
>&
args
)
override
{
return
std
::
get
<
0
>
(
args
)
-
std
::
get
<
1
>
(
args
);
}
};
TEST
(
WithArgsTest
,
NonInvokeAction
)
{
Action
<
int
(
const
std
::
string
&
,
int
,
int
)
>
a
=
WithArgs
<
2
,
1
>
(
MakeAction
(
new
SubtractAction
));
std
::
tuple
<
std
::
string
,
int
,
int
>
dummy
=
std
::
make_tuple
(
std
::
string
(
"hi"
),
2
,
10
);
EXPECT_EQ
(
8
,
a
.
Perform
(
dummy
));
}
// Tests using WithArgs to pass all original arguments in the original order.
TEST
(
WithArgsTest
,
Identity
)
{
Action
<
int
(
int
x
,
char
y
,
short
z
)
>
a
=
// NOLINT
WithArgs
<
0
,
1
,
2
>
(
Invoke
(
Ternary
));
EXPECT_EQ
(
123
,
a
.
Perform
(
std
::
make_tuple
(
100
,
Char
(
20
),
Short
(
3
))));
}
// Tests using WithArgs with repeated arguments.
TEST
(
WithArgsTest
,
RepeatedArguments
)
{
Action
<
int
(
bool
,
int
m
,
int
n
)
>
a
=
// NOLINT
WithArgs
<
1
,
1
,
1
,
1
>
(
Invoke
(
SumOf4
));
EXPECT_EQ
(
4
,
a
.
Perform
(
std
::
make_tuple
(
false
,
1
,
10
)));
}
// Tests using WithArgs with reversed argument order.
TEST
(
WithArgsTest
,
ReversedArgumentOrder
)
{
Action
<
const
char
*
(
short
n
,
const
char
*
input
)
>
a
=
// NOLINT
WithArgs
<
1
,
0
>
(
Invoke
(
Binary
));
const
char
s
[]
=
"Hello"
;
EXPECT_EQ
(
s
+
2
,
a
.
Perform
(
std
::
make_tuple
(
Short
(
2
),
CharPtr
(
s
))));
}
// Tests using WithArgs with compatible, but not identical, argument types.
TEST
(
WithArgsTest
,
ArgsOfCompatibleTypes
)
{
Action
<
long
(
short
x
,
char
y
,
double
z
,
char
c
)
>
a
=
// NOLINT
WithArgs
<
0
,
1
,
3
>
(
Invoke
(
Ternary
));
EXPECT_EQ
(
123
,
a
.
Perform
(
std
::
make_tuple
(
Short
(
100
),
Char
(
20
),
5.6
,
Char
(
3
))));
}
// Tests using WithArgs with an action that returns void.
TEST
(
WithArgsTest
,
VoidAction
)
{
Action
<
void
(
double
x
,
char
c
,
int
n
)
>
a
=
WithArgs
<
2
,
1
>
(
Invoke
(
VoidBinary
));
g_done
=
false
;
a
.
Perform
(
std
::
make_tuple
(
1.5
,
'a'
,
3
));
EXPECT_TRUE
(
g_done
);
}
TEST
(
WithArgsTest
,
ReturnReference
)
{
Action
<
int
&
(
int
&
,
void
*
)
>
aa
=
WithArgs
<
0
>
([](
int
&
a
)
->
int
&
{
return
a
;
});
int
i
=
0
;
const
int
&
res
=
aa
.
Perform
(
std
::
forward_as_tuple
(
i
,
nullptr
));
EXPECT_EQ
(
&
i
,
&
res
);
}
TEST
(
WithArgsTest
,
InnerActionWithConversion
)
{
Action
<
Derived
*
()
>
inner
=
[]
{
return
nullptr
;
};
Action
<
Base
*
(
double
)
>
a
=
testing
::
WithoutArgs
(
inner
);
EXPECT_EQ
(
nullptr
,
a
.
Perform
(
std
::
make_tuple
(
1.1
)));
}
#if !GTEST_OS_WINDOWS_MOBILE
class
SetErrnoAndReturnTest
:
public
testing
::
Test
{
protected
:
void
SetUp
()
override
{
errno
=
0
;
}
void
TearDown
()
override
{
errno
=
0
;
}
};
TEST_F
(
SetErrnoAndReturnTest
,
Int
)
{
Action
<
int
(
void
)
>
a
=
SetErrnoAndReturn
(
ENOTTY
,
-
5
);
EXPECT_EQ
(
-
5
,
a
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
ENOTTY
,
errno
);
}
TEST_F
(
SetErrnoAndReturnTest
,
Ptr
)
{
int
x
;
Action
<
int
*
(
void
)
>
a
=
SetErrnoAndReturn
(
ENOTTY
,
&
x
);
EXPECT_EQ
(
&
x
,
a
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
ENOTTY
,
errno
);
}
TEST_F
(
SetErrnoAndReturnTest
,
CompatibleTypes
)
{
Action
<
double
()
>
a
=
SetErrnoAndReturn
(
EINVAL
,
5
);
EXPECT_DOUBLE_EQ
(
5.0
,
a
.
Perform
(
std
::
make_tuple
()));
EXPECT_EQ
(
EINVAL
,
errno
);
}
#endif
// !GTEST_OS_WINDOWS_MOBILE
// Tests ByRef().
// Tests that the result of ByRef() is copyable.
TEST
(
ByRefTest
,
IsCopyable
)
{
const
std
::
string
s1
=
"Hi"
;
const
std
::
string
s2
=
"Hello"
;
auto
ref_wrapper
=
ByRef
(
s1
);
const
std
::
string
&
r1
=
ref_wrapper
;
EXPECT_EQ
(
&
s1
,
&
r1
);
// Assigns a new value to ref_wrapper.
ref_wrapper
=
ByRef
(
s2
);
const
std
::
string
&
r2
=
ref_wrapper
;
EXPECT_EQ
(
&
s2
,
&
r2
);
auto
ref_wrapper1
=
ByRef
(
s1
);
// Copies ref_wrapper1 to ref_wrapper.
ref_wrapper
=
ref_wrapper1
;
const
std
::
string
&
r3
=
ref_wrapper
;
EXPECT_EQ
(
&
s1
,
&
r3
);
}
// Tests using ByRef() on a const value.
TEST
(
ByRefTest
,
ConstValue
)
{
const
int
n
=
0
;
// int& ref = ByRef(n); // This shouldn't compile - we have a
// negative compilation test to catch it.
const
int
&
const_ref
=
ByRef
(
n
);
EXPECT_EQ
(
&
n
,
&
const_ref
);
}
// Tests using ByRef() on a non-const value.
TEST
(
ByRefTest
,
NonConstValue
)
{
int
n
=
0
;
// ByRef(n) can be used as either an int&,
int
&
ref
=
ByRef
(
n
);
EXPECT_EQ
(
&
n
,
&
ref
);
// or a const int&.
const
int
&
const_ref
=
ByRef
(
n
);
EXPECT_EQ
(
&
n
,
&
const_ref
);
}
// Tests explicitly specifying the type when using ByRef().
TEST
(
ByRefTest
,
ExplicitType
)
{
int
n
=
0
;
const
int
&
r1
=
ByRef
<
const
int
>
(
n
);
EXPECT_EQ
(
&
n
,
&
r1
);
// ByRef<char>(n); // This shouldn't compile - we have a negative
// compilation test to catch it.
Derived
d
;
Derived
&
r2
=
ByRef
<
Derived
>
(
d
);
EXPECT_EQ
(
&
d
,
&
r2
);
const
Derived
&
r3
=
ByRef
<
const
Derived
>
(
d
);
EXPECT_EQ
(
&
d
,
&
r3
);
Base
&
r4
=
ByRef
<
Base
>
(
d
);
EXPECT_EQ
(
&
d
,
&
r4
);
const
Base
&
r5
=
ByRef
<
const
Base
>
(
d
);
EXPECT_EQ
(
&
d
,
&
r5
);
// The following shouldn't compile - we have a negative compilation
// test for it.
//
// Base b;
// ByRef<Derived>(b);
}
// Tests that Google Mock prints expression ByRef(x) as a reference to x.
TEST
(
ByRefTest
,
PrintsCorrectly
)
{
int
n
=
42
;
::
std
::
stringstream
expected
,
actual
;
testing
::
internal
::
UniversalPrinter
<
const
int
&>::
Print
(
n
,
&
expected
);
testing
::
internal
::
UniversalPrint
(
ByRef
(
n
),
&
actual
);
EXPECT_EQ
(
expected
.
str
(),
actual
.
str
());
}
std
::
unique_ptr
<
int
>
UniquePtrSource
()
{
return
std
::
unique_ptr
<
int
>
(
new
int
(
19
));
}
std
::
vector
<
std
::
unique_ptr
<
int
>>
VectorUniquePtrSource
()
{
std
::
vector
<
std
::
unique_ptr
<
int
>>
out
;
out
.
emplace_back
(
new
int
(
7
));
return
out
;
}
TEST
(
MockMethodTest
,
CanReturnMoveOnlyValue_Return
)
{
MockClass
mock
;
std
::
unique_ptr
<
int
>
i
(
new
int
(
19
));
EXPECT_CALL
(
mock
,
MakeUnique
()).
WillOnce
(
Return
(
ByMove
(
std
::
move
(
i
))));
EXPECT_CALL
(
mock
,
MakeVectorUnique
())
.
WillOnce
(
Return
(
ByMove
(
VectorUniquePtrSource
())));
Derived
*
d
=
new
Derived
;
EXPECT_CALL
(
mock
,
MakeUniqueBase
())
.
WillOnce
(
Return
(
ByMove
(
std
::
unique_ptr
<
Derived
>
(
d
))));
std
::
unique_ptr
<
int
>
result1
=
mock
.
MakeUnique
();
EXPECT_EQ
(
19
,
*
result1
);
std
::
vector
<
std
::
unique_ptr
<
int
>>
vresult
=
mock
.
MakeVectorUnique
();
EXPECT_EQ
(
1u
,
vresult
.
size
());
EXPECT_NE
(
nullptr
,
vresult
[
0
]);
EXPECT_EQ
(
7
,
*
vresult
[
0
]);
std
::
unique_ptr
<
Base
>
result2
=
mock
.
MakeUniqueBase
();
EXPECT_EQ
(
d
,
result2
.
get
());
}
TEST
(
MockMethodTest
,
CanReturnMoveOnlyValue_DoAllReturn
)
{
testing
::
MockFunction
<
void
()
>
mock_function
;
MockClass
mock
;
std
::
unique_ptr
<
int
>
i
(
new
int
(
19
));
EXPECT_CALL
(
mock_function
,
Call
());
EXPECT_CALL
(
mock
,
MakeUnique
()).
WillOnce
(
DoAll
(
InvokeWithoutArgs
(
&
mock_function
,
&
testing
::
MockFunction
<
void
()
>::
Call
),
Return
(
ByMove
(
std
::
move
(
i
)))));
std
::
unique_ptr
<
int
>
result1
=
mock
.
MakeUnique
();
EXPECT_EQ
(
19
,
*
result1
);
}
TEST
(
MockMethodTest
,
CanReturnMoveOnlyValue_Invoke
)
{
MockClass
mock
;
// Check default value
DefaultValue
<
std
::
unique_ptr
<
int
>>::
SetFactory
([]
{
return
std
::
unique_ptr
<
int
>
(
new
int
(
42
));
});
EXPECT_EQ
(
42
,
*
mock
.
MakeUnique
());
EXPECT_CALL
(
mock
,
MakeUnique
()).
WillRepeatedly
(
Invoke
(
UniquePtrSource
));
EXPECT_CALL
(
mock
,
MakeVectorUnique
())
.
WillRepeatedly
(
Invoke
(
VectorUniquePtrSource
));
std
::
unique_ptr
<
int
>
result1
=
mock
.
MakeUnique
();
EXPECT_EQ
(
19
,
*
result1
);
std
::
unique_ptr
<
int
>
result2
=
mock
.
MakeUnique
();
EXPECT_EQ
(
19
,
*
result2
);
EXPECT_NE
(
result1
,
result2
);
std
::
vector
<
std
::
unique_ptr
<
int
>>
vresult
=
mock
.
MakeVectorUnique
();
EXPECT_EQ
(
1u
,
vresult
.
size
());
EXPECT_NE
(
nullptr
,
vresult
[
0
]);
EXPECT_EQ
(
7
,
*
vresult
[
0
]);
}
TEST
(
MockMethodTest
,
CanTakeMoveOnlyValue
)
{
MockClass
mock
;
auto
make
=
[](
int
i
)
{
return
std
::
unique_ptr
<
int
>
(
new
int
(
i
));
};
EXPECT_CALL
(
mock
,
TakeUnique
(
_
)).
WillRepeatedly
([](
std
::
unique_ptr
<
int
>
i
)
{
return
*
i
;
});
// DoAll() does not compile, since it would move from its arguments twice.
// EXPECT_CALL(mock, TakeUnique(_, _))
// .WillRepeatedly(DoAll(Invoke([](std::unique_ptr<int> j) {}),
// Return(1)));
EXPECT_CALL
(
mock
,
TakeUnique
(
testing
::
Pointee
(
7
)))
.
WillOnce
(
Return
(
-
7
))
.
RetiresOnSaturation
();
EXPECT_CALL
(
mock
,
TakeUnique
(
testing
::
IsNull
()))
.
WillOnce
(
Return
(
-
1
))
.
RetiresOnSaturation
();
EXPECT_EQ
(
5
,
mock
.
TakeUnique
(
make
(
5
)));
EXPECT_EQ
(
-
7
,
mock
.
TakeUnique
(
make
(
7
)));
EXPECT_EQ
(
7
,
mock
.
TakeUnique
(
make
(
7
)));
EXPECT_EQ
(
7
,
mock
.
TakeUnique
(
make
(
7
)));
EXPECT_EQ
(
-
1
,
mock
.
TakeUnique
({}));
// Some arguments are moved, some passed by reference.
auto
lvalue
=
make
(
6
);
EXPECT_CALL
(
mock
,
TakeUnique
(
_
,
_
))
.
WillOnce
([](
const
std
::
unique_ptr
<
int
>&
i
,
std
::
unique_ptr
<
int
>
j
)
{
return
*
i
*
*
j
;
});
EXPECT_EQ
(
42
,
mock
.
TakeUnique
(
lvalue
,
make
(
7
)));
// The unique_ptr can be saved by the action.
std
::
unique_ptr
<
int
>
saved
;
EXPECT_CALL
(
mock
,
TakeUnique
(
_
)).
WillOnce
([
&
saved
](
std
::
unique_ptr
<
int
>
i
)
{
saved
=
std
::
move
(
i
);
return
0
;
});
EXPECT_EQ
(
0
,
mock
.
TakeUnique
(
make
(
42
)));
EXPECT_EQ
(
42
,
*
saved
);
}
// Tests for std::function based action.
int
Add
(
int
val
,
int
&
ref
,
int
*
ptr
)
{
// NOLINT
int
result
=
val
+
ref
+
*
ptr
;
ref
=
42
;
*
ptr
=
43
;
return
result
;
}
int
Deref
(
std
::
unique_ptr
<
int
>
ptr
)
{
return
*
ptr
;
}
struct
Double
{
template
<
typename
T
>
T
operator
()(
T
t
)
{
return
2
*
t
;
}
};
std
::
unique_ptr
<
int
>
UniqueInt
(
int
i
)
{
return
std
::
unique_ptr
<
int
>
(
new
int
(
i
));
}
TEST
(
FunctorActionTest
,
ActionFromFunction
)
{
Action
<
int
(
int
,
int
&
,
int
*
)
>
a
=
&
Add
;
int
x
=
1
,
y
=
2
,
z
=
3
;
EXPECT_EQ
(
6
,
a
.
Perform
(
std
::
forward_as_tuple
(
x
,
y
,
&
z
)));
EXPECT_EQ
(
42
,
y
);
EXPECT_EQ
(
43
,
z
);
Action
<
int
(
std
::
unique_ptr
<
int
>
)
>
a1
=
&
Deref
;
EXPECT_EQ
(
7
,
a1
.
Perform
(
std
::
make_tuple
(
UniqueInt
(
7
))));
}
TEST
(
FunctorActionTest
,
ActionFromLambda
)
{
Action
<
int
(
bool
,
int
)
>
a1
=
[](
bool
b
,
int
i
)
{
return
b
?
i
:
0
;
};
EXPECT_EQ
(
5
,
a1
.
Perform
(
std
::
make_tuple
(
true
,
5
)));
EXPECT_EQ
(
0
,
a1
.
Perform
(
std
::
make_tuple
(
false
,
5
)));
std
::
unique_ptr
<
int
>
saved
;
Action
<
void
(
std
::
unique_ptr
<
int
>
)
>
a2
=
[
&
saved
](
std
::
unique_ptr
<
int
>
p
)
{
saved
=
std
::
move
(
p
);
};
a2
.
Perform
(
std
::
make_tuple
(
UniqueInt
(
5
)));
EXPECT_EQ
(
5
,
*
saved
);
}
TEST
(
FunctorActionTest
,
PolymorphicFunctor
)
{
Action
<
int
(
int
)
>
ai
=
Double
();
EXPECT_EQ
(
2
,
ai
.
Perform
(
std
::
make_tuple
(
1
)));
Action
<
double
(
double
)
>
ad
=
Double
();
// Double? Double double!
EXPECT_EQ
(
3.0
,
ad
.
Perform
(
std
::
make_tuple
(
1.5
)));
}
TEST
(
FunctorActionTest
,
TypeConversion
)
{
// Numeric promotions are allowed.
const
Action
<
bool
(
int
)
>
a1
=
[](
int
i
)
{
return
i
>
1
;
};
const
Action
<
int
(
bool
)
>
a2
=
Action
<
int
(
bool
)
>
(
a1
);
EXPECT_EQ
(
1
,
a1
.
Perform
(
std
::
make_tuple
(
42
)));
EXPECT_EQ
(
0
,
a2
.
Perform
(
std
::
make_tuple
(
42
)));
// Implicit constructors are allowed.
const
Action
<
bool
(
std
::
string
)
>
s1
=
[](
std
::
string
s
)
{
return
!
s
.
empty
();
};
const
Action
<
int
(
const
char
*
)
>
s2
=
Action
<
int
(
const
char
*
)
>
(
s1
);
EXPECT_EQ
(
0
,
s2
.
Perform
(
std
::
make_tuple
(
""
)));
EXPECT_EQ
(
1
,
s2
.
Perform
(
std
::
make_tuple
(
"hello"
)));
// Also between the lambda and the action itself.
const
Action
<
bool
(
std
::
string
)
>
x
=
[](
Unused
)
{
return
42
;
};
EXPECT_TRUE
(
x
.
Perform
(
std
::
make_tuple
(
"hello"
)));
}
TEST
(
FunctorActionTest
,
UnusedArguments
)
{
// Verify that users can ignore uninteresting arguments.
Action
<
int
(
int
,
double
y
,
double
z
)
>
a
=
[](
int
i
,
Unused
,
Unused
)
{
return
2
*
i
;
};
std
::
tuple
<
int
,
double
,
double
>
dummy
=
std
::
make_tuple
(
3
,
7.3
,
9.44
);
EXPECT_EQ
(
6
,
a
.
Perform
(
dummy
));
}
// Test that basic built-in actions work with move-only arguments.
TEST
(
MoveOnlyArgumentsTest
,
ReturningActions
)
{
Action
<
int
(
std
::
unique_ptr
<
int
>
)
>
a
=
Return
(
1
);
EXPECT_EQ
(
1
,
a
.
Perform
(
std
::
make_tuple
(
nullptr
)));
a
=
testing
::
WithoutArgs
([]()
{
return
7
;
});
EXPECT_EQ
(
7
,
a
.
Perform
(
std
::
make_tuple
(
nullptr
)));
Action
<
void
(
std
::
unique_ptr
<
int
>
,
int
*
)
>
a2
=
testing
::
SetArgPointee
<
1
>
(
3
);
int
x
=
0
;
a2
.
Perform
(
std
::
make_tuple
(
nullptr
,
&
x
));
EXPECT_EQ
(
x
,
3
);
}
}
// Unnamed namespace
#ifdef _MSC_VER
#if _MSC_VER == 1900
# pragma warning(pop)
#endif
#endif
Event Timeline
Log In to Comment