Commit 10f05a62 authored by Tanzinul Islam's avatar Tanzinul Islam
Browse files

Merge branch 'master' into fix_death_test_child_mingw_wer_issue1116

parents 5c7c365d 278aba36
...@@ -37,13 +37,15 @@ matrix: ...@@ -37,13 +37,15 @@ matrix:
group: deprecated-2017Q4 group: deprecated-2017Q4
compiler: clang compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
- os: linux
compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 NO_EXCEPTION=ON NO_RTTI=ON COMPILER_IS_GNUCXX=ON
- os: osx - os: osx
compiler: gcc compiler: gcc
env: BUILD_TYPE=Debug VERBOSE=1 env: BUILD_TYPE=Debug VERBOSE=1
- os: osx - os: osx
compiler: gcc compiler: gcc
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
if: type != pull_request
- os: osx - os: osx
compiler: clang compiler: clang
env: BUILD_TYPE=Debug VERBOSE=1 env: BUILD_TYPE=Debug VERBOSE=1
......
...@@ -24,11 +24,19 @@ export MAKEFLAGS ...@@ -24,11 +24,19 @@ export MAKEFLAGS
env | sort env | sort
# Set default values to OFF for these variables if not specified.
: "${NO_EXCEPTION:=OFF}"
: "${NO_RTTI:=OFF}"
: "${COMPILER_IS_GNUCXX:=OFF}"
mkdir build || true mkdir build || true
cd build cd build
cmake -Dgtest_build_samples=ON \ cmake -Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \ -Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \ -Dgmock_build_tests=ON \
-Dcxx_no_exception=$NO_EXCEPTION \
-Dcxx_no_rtti=$NO_RTTI \
-DCMAKE_COMPILER_IS_GNUCXX=$COMPILER_IS_GNUCXX \
-DCMAKE_CXX_FLAGS=$CXX_FLAGS \ -DCMAKE_CXX_FLAGS=$CXX_FLAGS \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \ -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
.. ..
......
...@@ -2229,13 +2229,20 @@ versus ...@@ -2229,13 +2229,20 @@ versus
## Mocking Methods That Use Move-Only Types ## ## Mocking Methods That Use Move-Only Types ##
C++11 introduced <em>move-only types</em>. A move-only-typed value can be moved from one object to another, but cannot be copied. `std::unique_ptr<T>` is probably the most commonly used move-only type. C++11 introduced *move-only types*. A move-only-typed value can be moved from
one object to another, but cannot be copied. `std::unique_ptr<T>` is
probably the most commonly used move-only type.
Mocking a method that takes and/or returns move-only types presents some challenges, but nothing insurmountable. This recipe shows you how you can do it. Mocking a method that takes and/or returns move-only types presents some
challenges, but nothing insurmountable. This recipe shows you how you can do it.
Note that the support for move-only method arguments was only introduced to
gMock in April 2017; in older code, you may find more complex
[workarounds](#LegacyMoveOnly) for lack of this feature.
Let’s say we are working on a fictional project that lets one post and share snippets called “buzzes”. Your code uses these types: Let’s say we are working on a fictional project that lets one post and share
snippets called “buzzes”. Your code uses these types:
``` ```cpp
enum class AccessLevel { kInternal, kPublic }; enum class AccessLevel { kInternal, kPublic };
class Buzz { class Buzz {
...@@ -2247,59 +2254,46 @@ class Buzz { ...@@ -2247,59 +2254,46 @@ class Buzz {
class Buzzer { class Buzzer {
public: public:
virtual ~Buzzer() {} virtual ~Buzzer() {}
virtual std::unique_ptr<Buzz> MakeBuzz(const std::string& text) = 0; virtual std::unique_ptr<Buzz> MakeBuzz(StringPiece text) = 0;
virtual bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) = 0; virtual bool ShareBuzz(std::unique_ptr<Buzz> buzz, int64_t timestamp) = 0;
... ...
}; };
``` ```
A `Buzz` object represents a snippet being posted. A class that implements the `Buzzer` interface is capable of creating and sharing `Buzz`. Methods in `Buzzer` may return a `unique_ptr<Buzz>` or take a `unique_ptr<Buzz>`. Now we need to mock `Buzzer` in our tests. A `Buzz` object represents a snippet being posted. A class that implements the
`Buzzer` interface is capable of creating and sharing `Buzz`es. Methods in
To mock a method that returns a move-only type, you just use the familiar `MOCK_METHOD` syntax as usual: `Buzzer` may return a `unique_ptr<Buzz>` or take a
`unique_ptr<Buzz>`. Now we need to mock `Buzzer` in our tests.
```
class MockBuzzer : public Buzzer {
public:
MOCK_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(const std::string& text));
};
```
However, if you attempt to use the same `MOCK_METHOD` pattern to mock a method that takes a move-only parameter, you’ll get a compiler error currently:
```
// Does NOT compile!
MOCK_METHOD2(ShareBuzz, bool(std::unique_ptr<Buzz> buzz, Time timestamp));
```
While it’s highly desirable to make this syntax just work, it’s not trivial and the work hasn’t been done yet. Fortunately, there is a trick you can apply today to get something that works nearly as well as this.
The trick, is to delegate the `ShareBuzz()` method to a mock method (let’s call it `DoShareBuzz()`) that does not take move-only parameters: To mock a method that accepts or returns move-only types, you just use the
familiar `MOCK_METHOD` syntax as usual:
``` ```cpp
class MockBuzzer : public Buzzer { class MockBuzzer : public Buzzer {
public: public:
MOCK_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(const std::string& text)); MOCK_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(StringPiece text));
MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp)); MOCK_METHOD2(ShareBuzz, bool(std::unique_ptr<Buzz> buzz, int64_t timestamp));
bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) {
return DoShareBuzz(buzz.get(), timestamp);
}
}; };
``` ```
Note that there's no need to define or declare `DoShareBuzz()` in a base class. You only need to define it as a `MOCK_METHOD` in the mock class. Now that we have the mock class defined, we can use it in tests. In the
following code examples, we assume that we have defined a `MockBuzzer` object
Now that we have the mock class defined, we can use it in tests. In the following code examples, we assume that we have defined a `MockBuzzer` object named `mock_buzzer_`: named `mock_buzzer_`:
``` ```cpp
MockBuzzer mock_buzzer_; MockBuzzer mock_buzzer_;
``` ```
First let’s see how we can set expectations on the `MakeBuzz()` method, which returns a `unique_ptr<Buzz>`. First let’s see how we can set expectations on the `MakeBuzz()` method, which
returns a `unique_ptr<Buzz>`.
As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or `.WillRepeated()` clause), when that expectation fires, the default action for that method will be taken. Since `unique_ptr<>` has a default constructor that returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an action: As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or
`.WillRepeated()` clause), when that expectation fires, the default action for
that method will be taken. Since `unique_ptr<>` has a default constructor
that returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an
action:
``` ```cpp
// Use the default action. // Use the default action.
EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")); EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"));
...@@ -2307,32 +2301,13 @@ As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or ...@@ -2307,32 +2301,13 @@ As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or
EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello")); EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello"));
``` ```
If you are not happy with the default action, you can tweak it. Depending on what you need, you may either tweak the default action for a specific (mock object, mock method) combination using `ON_CALL()`, or you may tweak the default action for all mock methods that return a specific type. The usage of `ON_CALL()` is similar to `EXPECT_CALL()`, so we’ll skip it and just explain how to do the latter (tweaking the default action for a specific return type). You do this via the `DefaultValue<>::SetFactory()` and `DefaultValue<>::Clear()` API: If you are not happy with the default action, you can tweak it as usual; see
[Setting Default Actions](#OnCall).
```
// Sets the default action for return type std::unique_ptr<Buzz> to
// creating a new Buzz every time.
DefaultValue<std::unique_ptr<Buzz>>::SetFactory(
[] { return MakeUnique<Buzz>(AccessLevel::kInternal); });
// When this fires, the default action of MakeBuzz() will run, which
// will return a new Buzz object.
EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber());
auto buzz1 = mock_buzzer_.MakeBuzz("hello"); If you just need to return a pre-defined move-only value, you can use the
auto buzz2 = mock_buzzer_.MakeBuzz("hello"); `Return(ByMove(...))` action:
EXPECT_NE(nullptr, buzz1);
EXPECT_NE(nullptr, buzz2);
EXPECT_NE(buzz1, buzz2);
// Resets the default action for return type std::unique_ptr<Buzz>, ```cpp
// to avoid interfere with other tests.
DefaultValue<std::unique_ptr<Buzz>>::Clear();
```
What if you want the method to do something other than the default action? If you just need to return a pre-defined move-only value, you can use the `Return(ByMove(...))` action:
```
// When this fires, the unique_ptr<> specified by ByMove(...) will // When this fires, the unique_ptr<> specified by ByMove(...) will
// be returned. // be returned.
EXPECT_CALL(mock_buzzer_, MakeBuzz("world")) EXPECT_CALL(mock_buzzer_, MakeBuzz("world"))
...@@ -2343,81 +2318,87 @@ What if you want the method to do something other than the default action? If y ...@@ -2343,81 +2318,87 @@ What if you want the method to do something other than the default action? If y
Note that `ByMove()` is essential here - if you drop it, the code won’t compile. Note that `ByMove()` is essential here - if you drop it, the code won’t compile.
Quiz time! What do you think will happen if a `Return(ByMove(...))` action is performed more than once (e.g. you write `….WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time the action runs, the source value will be consumed (since it’s a move-only value), so the next time around, there’s no value to move from -- you’ll get a run-time error that `Return(ByMove(...))` can only be run once. Quiz time! What do you think will happen if a `Return(ByMove(...))` action is
performed more than once (e.g. you write
`….WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first
time the action runs, the source value will be consumed (since it’s a move-only
value), so the next time around, there’s no value to move from -- you’ll get a
run-time error that `Return(ByMove(...))` can only be run once.
If you need your mock method to do more than just moving a pre-defined value, remember that you can always use `Invoke()` to call a lambda or a callable object, which can do pretty much anything you want: If you need your mock method to do more than just moving a pre-defined value,
remember that you can always use a lambda or a callable object, which can do
pretty much anything you want:
``` ```cpp
EXPECT_CALL(mock_buzzer_, MakeBuzz("x")) EXPECT_CALL(mock_buzzer_, MakeBuzz("x"))
.WillRepeatedly(Invoke([](const std::string& text) { .WillRepeatedly([](StringPiece text) {
return std::make_unique<Buzz>(AccessLevel::kInternal); return MakeUnique<Buzz>(AccessLevel::kInternal);
})); });
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
``` ```
Every time this `EXPECT_CALL` fires, a new `unique_ptr<Buzz>` will be created and returned. You cannot do this with `Return(ByMove(...))`. Every time this `EXPECT_CALL` fires, a new `unique_ptr<Buzz>` will be
created and returned. You cannot do this with `Return(ByMove(...))`.
Now there’s one topic we haven’t covered: how do you set expectations on `ShareBuzz()`, which takes a move-only-typed parameter? The answer is you don’t. Instead, you set expectations on the `DoShareBuzz()` mock method (remember that we defined a `MOCK_METHOD` for `DoShareBuzz()`, not `ShareBuzz()`): That covers returning move-only values; but how do we work with methods
accepting move-only arguments? The answer is that they work normally, although
some actions will not compile when any of method's arguments are move-only. You
can always use `Return`, or a [lambda or functor](#FunctionsAsActions):
``` ```cpp
EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)); using ::testing::Unused;
// When one calls ShareBuzz() on the MockBuzzer like this, the call is EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)) .WillOnce(Return(true));
// forwarded to DoShareBuzz(), which is mocked. Therefore this statement EXPECT_TRUE(mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal)),
// will trigger the above EXPECT_CALL. 0);
mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal),
::base::Now()); EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)) .WillOnce(
[](std::unique_ptr<Buzz> buzz, Unused) { return buzz != nullptr; });
EXPECT_FALSE(mock_buzzer_.ShareBuzz(nullptr, 0));
``` ```
Some of you may have spotted one problem with this approach: the `DoShareBuzz()` mock method differs from the real `ShareBuzz()` method in that it cannot take ownership of the buzz parameter - `ShareBuzz()` will always delete buzz after `DoShareBuzz()` returns. What if you need to save the buzz object somewhere for later use when `ShareBuzz()` is called? Indeed, you'd be stuck. Many built-in actions (`WithArgs`, `WithoutArgs`,`DeleteArg`, `SaveArg`, ...)
could in principle support move-only arguments, but the support for this is not
implemented yet. If this is blocking you, please file a bug.
Another problem with the `DoShareBuzz()` we had is that it can surprise people reading or maintaining the test, as one would expect that `DoShareBuzz()` has (logically) the same contract as `ShareBuzz()`. A few actions (e.g. `DoAll`) copy their arguments internally, so they can never
work with non-copyable objects; you'll have to use functors instead.
Fortunately, these problems can be fixed with a bit more code. Let's try to get it right this time: ##### Legacy workarounds for move-only types {#LegacyMoveOnly}
``` Support for move-only function arguments was only introduced to gMock in April
2017. In older code, you may encounter the following workaround for the lack of
this feature (it is no longer necessary - we're including it just for
reference):
```cpp
class MockBuzzer : public Buzzer { class MockBuzzer : public Buzzer {
public: public:
MockBuzzer() {
// Since DoShareBuzz(buzz, time) is supposed to take ownership of
// buzz, define a default behavior for DoShareBuzz(buzz, time) to
// delete buzz.
ON_CALL(*this, DoShareBuzz(_, _))
.WillByDefault(Invoke([](Buzz* buzz, Time timestamp) {
delete buzz;
return true;
}));
}
MOCK_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(const std::string& text));
// Takes ownership of buzz.
MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp)); MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp));
bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) { bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) override {
return DoShareBuzz(buzz.release(), timestamp); return DoShareBuzz(buzz.get(), timestamp);
} }
}; };
``` ```
Now, the mock `DoShareBuzz()` method is free to save the buzz argument for later use if this is what you want: The trick is to delegate the `ShareBuzz()` method to a mock method (let’s call
it `DoShareBuzz()`) that does not take move-only parameters. Then, instead of
setting expectations on `ShareBuzz()`, you set them on the `DoShareBuzz()` mock
method:
``` ```cpp
std::unique_ptr<Buzz> intercepted_buzz; MockBuzzer mock_buzzer_;
EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)) EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _));
.WillOnce(Invoke([&intercepted_buzz](Buzz* buzz, Time timestamp) {
// Save buzz in intercepted_buzz for analysis later.
intercepted_buzz.reset(buzz);
return false;
}));
mock_buzzer_.ShareBuzz(std::make_unique<Buzz>(AccessLevel::kInternal), // When one calls ShareBuzz() on the MockBuzzer like this, the call is
Now()); // forwarded to DoShareBuzz(), which is mocked. Therefore this statement
EXPECT_NE(nullptr, intercepted_buzz); // will trigger the above EXPECT_CALL.
mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal), 0);
``` ```
Using the tricks covered in this recipe, you are now able to mock methods that take and/or return move-only types. Put your newly-acquired power to good use - when you design a new API, you can now feel comfortable using `unique_ptrs` as appropriate, without fearing that doing so will compromise your tests.
## Making the Compilation Faster ## ## Making the Compilation Faster ##
......
...@@ -360,14 +360,20 @@ class Action { ...@@ -360,14 +360,20 @@ class Action {
// Constructs a null Action. Needed for storing Action objects in // Constructs a null Action. Needed for storing Action objects in
// STL containers. // STL containers.
Action() : impl_(NULL) {} Action() {}
// Constructs an Action from its implementation. A NULL impl is #if GTEST_LANG_CXX11
// used to represent the "do-default" action. // Construct an Action from a specified callable.
explicit Action(ActionInterface<F>* impl) : impl_(impl) {} // This cannot take std::function directly, because then Action would not be
// directly constructible from lambda (it would require two conversions).
template <typename G,
typename = typename ::std::enable_if<
::std::is_constructible<::std::function<F>, G>::value>::type>
Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT
#endif
// Copy constructor. // Constructs an Action from its implementation.
Action(const Action& action) : impl_(action.impl_) {} explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
// This constructor allows us to turn an Action<Func> object into an // This constructor allows us to turn an Action<Func> object into an
// Action<F>, as long as F's arguments can be implicitly converted // Action<F>, as long as F's arguments can be implicitly converted
...@@ -377,7 +383,13 @@ class Action { ...@@ -377,7 +383,13 @@ class Action {
explicit Action(const Action<Func>& action); explicit Action(const Action<Func>& action);
// Returns true iff this is the DoDefault() action. // Returns true iff this is the DoDefault() action.
bool IsDoDefault() const { return impl_.get() == NULL; } bool IsDoDefault() const {
#if GTEST_LANG_CXX11
return impl_ == nullptr && fun_ == nullptr;
#else
return impl_ == NULL;
#endif
}
// Performs the action. Note that this method is const even though // Performs the action. Note that this method is const even though
// the corresponding method in ActionInterface is not. The reason // the corresponding method in ActionInterface is not. The reason
...@@ -385,14 +397,15 @@ class Action { ...@@ -385,14 +397,15 @@ class Action {
// another concrete action, not that the concrete action it binds to // another concrete action, not that the concrete action it binds to
// cannot change state. (Think of the difference between a const // cannot change state. (Think of the difference between a const
// pointer and a pointer to const.) // pointer and a pointer to const.)
Result Perform(const ArgumentTuple& args) const { Result Perform(ArgumentTuple args) const {
internal::Assert( if (IsDoDefault()) {
!IsDoDefault(), __FILE__, __LINE__, internal::IllegalDoDefault(__FILE__, __LINE__);
"You are using DoDefault() inside a composite action like " }
"DoAll() or WithArgs(). This is not supported for technical " #if GTEST_LANG_CXX11
"reasons. Please instead spell out the default action, or " if (fun_ != nullptr) {
"assign the default action to an Action variable and use " return internal::Apply(fun_, ::std::move(args));
"the variable in various places."); }
#endif
return impl_->Perform(args); return impl_->Perform(args);
} }
...@@ -400,6 +413,18 @@ class Action { ...@@ -400,6 +413,18 @@ class Action {
template <typename F1, typename F2> template <typename F1, typename F2>
friend class internal::ActionAdaptor; friend class internal::ActionAdaptor;
template <typename G>
friend class Action;
// In C++11, Action can be implemented either as a generic functor (through
// std::function), or legacy ActionInterface. In C++98, only ActionInterface
// is available. The invariants are as follows:
// * in C++98, impl_ is null iff this is the default action
// * in C++11, at most one of fun_ & impl_ may be nonnull; both are null iff
// this is the default action
#if GTEST_LANG_CXX11
::std::function<F> fun_;
#endif
internal::linked_ptr<ActionInterface<F> > impl_; internal::linked_ptr<ActionInterface<F> > impl_;
}; };
...@@ -531,6 +556,9 @@ struct ByMoveWrapper { ...@@ -531,6 +556,9 @@ struct ByMoveWrapper {
// statement, and conversion of the result of Return to Action<T(U)> is a // statement, and conversion of the result of Return to Action<T(U)> is a
// good place for that. // good place for that.
// //
// The real life example of the above scenario happens when an invocation
// of gtl::Container() is passed into Return.
//
template <typename R> template <typename R>
class ReturnAction { class ReturnAction {
public: public:
...@@ -750,7 +778,7 @@ class DoDefaultAction { ...@@ -750,7 +778,7 @@ class DoDefaultAction {
// This template type conversion operator allows DoDefault() to be // This template type conversion operator allows DoDefault() to be
// used in any function. // used in any function.
template <typename F> template <typename F>
operator Action<F>() const { return Action<F>(NULL); } operator Action<F>() const { return Action<F>(); } // NOLINT
}; };
// Implements the Assign action to set a given pointer referent to a // Implements the Assign action to set a given pointer referent to a
...@@ -886,6 +914,28 @@ class InvokeMethodWithoutArgsAction { ...@@ -886,6 +914,28 @@ class InvokeMethodWithoutArgsAction {
GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction); GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction);
}; };
// Implements the InvokeWithoutArgs(callback) action.
template <typename CallbackType>
class InvokeCallbackWithoutArgsAction {
public:
// The c'tor takes ownership of the callback.
explicit InvokeCallbackWithoutArgsAction(CallbackType* callback)
: callback_(callback) {
callback->CheckIsRepeatable(); // Makes sure the callback is permanent.
}
// This type conversion operator template allows Invoke(callback) to
// be used wherever the callback's return type can be implicitly
// converted to that of the mock function.
template <typename Result, typename ArgumentTuple>
Result Perform(const ArgumentTuple&) const { return callback_->Run(); }
private:
const internal::linked_ptr<CallbackType> callback_;
GTEST_DISALLOW_ASSIGN_(InvokeCallbackWithoutArgsAction);
};
// Implements the IgnoreResult(action) action. // Implements the IgnoreResult(action) action.
template <typename A> template <typename A>
class IgnoreResultAction { class IgnoreResultAction {
...@@ -1053,7 +1103,13 @@ typedef internal::IgnoredValue Unused; ...@@ -1053,7 +1103,13 @@ typedef internal::IgnoredValue Unused;
template <typename To> template <typename To>
template <typename From> template <typename From>
Action<To>::Action(const Action<From>& from) Action<To>::Action(const Action<From>& from)
: impl_(new internal::ActionAdaptor<To, From>(from)) {} :
#if GTEST_LANG_CXX11
fun_(from.fun_),
#endif
impl_(from.impl_ == NULL ? NULL
: new internal::ActionAdaptor<To, From>(from)) {
}
// Creates an action that returns 'value'. 'value' is passed by value // Creates an action that returns 'value'. 'value' is passed by value
// instead of const reference - otherwise Return("string literal") // instead of const reference - otherwise Return("string literal")
......
$$ -*- mode: c++; -*- $$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to $$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-actions.h. $$ gmock-generated-actions.h.
$$ $$
$var n = 10 $$ The maximum arity we support. $var n = 10 $$ The maximum arity we support.
...@@ -49,12 +49,13 @@ namespace testing { ...@@ -49,12 +49,13 @@ namespace testing {
namespace internal { namespace internal {
// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary // InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
// function or method with the unpacked values, where F is a function // function, method, or callback with the unpacked values, where F is
// type that takes N arguments. // a function type that takes N arguments.
template <typename Result, typename ArgumentTuple> template <typename Result, typename ArgumentTuple>
class InvokeHelper; class InvokeHelper;
$var max_callback_arity = 5
$range i 0..n $range i 0..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
...@@ -76,10 +77,48 @@ class InvokeHelper<R, ::testing::tuple<$as> > { ...@@ -76,10 +77,48 @@ class InvokeHelper<R, ::testing::tuple<$as> > {
const ::testing::tuple<$as>&$args) { const ::testing::tuple<$as>&$args) {
return (obj_ptr->*method_ptr)($gets); return (obj_ptr->*method_ptr)($gets);
} }
$if i <= max_callback_arity [[
template <typename CallbackType>
static R InvokeCallback(CallbackType* callback,
const ::testing::tuple<$as>&$args) {
return callback->Run($gets);
}
]] $else [[
// There is no InvokeCallback() for $i-tuples, as google3 callbacks
// support $max_callback_arity arguments at most.
]]
}; };
]] ]]
// Implements the Invoke(callback) action.
template <typename CallbackType>
class InvokeCallbackAction {
public:
// The c'tor takes ownership of the callback.
explicit InvokeCallbackAction(CallbackType* callback)
: callback_(callback) {
callback->CheckIsRepeatable(); // Makes sure the callback is permanent.
}
// This type conversion operator template allows Invoke(callback) to
// be used wherever the callback's type is compatible with that of
// the mock function, i.e. if the mock function's arguments can be
// implicitly converted to the callback's arguments and the
// callback's result can be implicitly converted to the mock
// function's result.
template <typename Result, typename ArgumentTuple>
Result Perform(const ArgumentTuple& args) const {
return InvokeHelper<Result, ArgumentTuple>::InvokeCallback(
callback_.get(), args);
}
private:
const linked_ptr<CallbackType> callback_;
};
// An INTERNAL macro for extracting the type of a tuple field. It's // An INTERNAL macro for extracting the type of a tuple field. It's
// subject to change without notice - DO NOT USE IN USER CODE! // subject to change without notice - DO NOT USE IN USER CODE!
#define GMOCK_FIELD_(Tuple, N) \ #define GMOCK_FIELD_(Tuple, N) \
...@@ -486,7 +525,7 @@ _VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]] ...@@ -486,7 +525,7 @@ _VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
$for i [[ $for i [[
$range j 0..i-1 $range j 0..i-1
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\ #define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]] ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::testing::internal::move(gmock_p$j))]]
]] ]]
...@@ -619,7 +658,7 @@ $var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]] ...@@ -619,7 +658,7 @@ $var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
$range j 0..i-1 $range j 0..i-1
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] $var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] $var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] $var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::forward<p$j##_type>(gmock_p$j))]]]]]]
$var param_field_decls = [[$for j $var param_field_decls = [[$for j
[[ [[
......
$$ -*- mode: c++; -*- $$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to $$ This is a Pump source file. Please use Pump to convert
$$ gmock-generated-function-mockers.h. $$ it to gmock-generated-function-mockers.h.
$$ $$
$var n = 10 $$ The maximum arity we support. $var n = 10 $$ The maximum arity we support.
// Copyright 2007, Google Inc. // Copyright 2007, Google Inc.
...@@ -68,7 +68,7 @@ $for i [[ ...@@ -68,7 +68,7 @@ $for i [[
$range j 1..i $range j 1..i
$var typename_As = [[$for j [[, typename A$j]]]] $var typename_As = [[$for j [[, typename A$j]]]]
$var As = [[$for j, [[A$j]]]] $var As = [[$for j, [[A$j]]]]
$var as = [[$for j, [[a$j]]]] $var as = [[$for j, [[internal::forward<A$j>(a$j)]]]]
$var Aas = [[$for j, [[A$j a$j]]]] $var Aas = [[$for j, [[A$j a$j]]]]
$var ms = [[$for j, [[m$j]]]] $var ms = [[$for j, [[m$j]]]]
$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]] $var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
...@@ -79,13 +79,8 @@ class FunctionMocker<R($As)> : public ...@@ -79,13 +79,8 @@ class FunctionMocker<R($As)> : public
typedef R F($As); typedef R F($As);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With($matchers) { MockSpec<F> With($matchers) {
return MockSpec<F>(this, ::testing::make_tuple($ms));
$if i >= 1 [[
this->current_spec().SetMatchers(::testing::make_tuple($ms));
]]
return this->current_spec();
} }
R Invoke($Aas) { R Invoke($Aas) {
...@@ -99,6 +94,58 @@ $if i >= 1 [[ ...@@ -99,6 +94,58 @@ $if i >= 1 [[
]] ]]
// Removes the given pointer; this is a helper for the expectation setter method
// for parameterless matchers.
//
// We want to make sure that the user cannot set a parameterless expectation on
// overloaded methods, including methods which are overloaded on const. Example:
//
// class MockClass {
// MOCK_METHOD0(GetName, string&());
// MOCK_CONST_METHOD0(GetName, const string&());
// };
//
// TEST() {
// // This should be an error, as it's not clear which overload is expected.
// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
// }
//
// Here are the generated expectation-setter methods:
//
// class MockClass {
// // Overload 1
// MockSpec<string&()> gmock_GetName() { … }
// // Overload 2. Declared const so that the compiler will generate an
// // error when trying to resolve between this and overload 4 in
// // 'gmock_GetName(WithoutMatchers(), nullptr)'.
// MockSpec<string&()> gmock_GetName(
// const WithoutMatchers&, const Function<string&()>*) const {
// // Removes const from this, calls overload 1
// return AdjustConstness_(this)->gmock_GetName();
// }
//
// // Overload 3
// const string& gmock_GetName() const { … }
// // Overload 4
// MockSpec<const string&()> gmock_GetName(
// const WithoutMatchers&, const Function<const string&()>*) const {
// // Does not remove const, calls overload 3
// return AdjustConstness_const(this)->gmock_GetName();
// }
// }
//
template <typename MockType>
const MockType* AdjustConstness_const(const MockType* mock) {
return mock;
}
// Removes const from and returns the given pointer; this is a helper for the
// expectation setter method for parameterless matchers.
template <typename MockType>
MockType* AdjustConstness_(const MockType* mock) {
return const_cast<MockType*>(mock);
}
} // namespace internal } // namespace internal
// The style guide prohibits "using" statements in a namespace scope // The style guide prohibits "using" statements in a namespace scope
...@@ -134,11 +181,14 @@ using internal::FunctionMocker; ...@@ -134,11 +181,14 @@ using internal::FunctionMocker;
$for i [[ $for i [[
$range j 1..i $range j 1..i
$var arg_as = [[$for j, \ $var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
[[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] $var as = [[$for j, \
$var as = [[$for j, [[gmock_a$j]]]] [[::testing::internal::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]]
$var matcher_as = [[$for j, \ $var matcher_arg_as = [[$for j, \
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
$var matcher_as = [[$for j, [[gmock_a$j]]]]
$var anything_matchers = [[$for j, \
[[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]]
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ #define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
...@@ -149,11 +199,17 @@ $var matcher_as = [[$for j, \ ...@@ -149,11 +199,17 @@ $var matcher_as = [[$for j, \
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
} \ } \
::testing::MockSpec<__VA_ARGS__>& \ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method($matcher_as) constness { \ gmock_##Method($matcher_arg_as) constness { \
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_($i, constness, Method).With($as); \ return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \
} \ } \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method($anything_matchers); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
...@@ -263,7 +319,7 @@ class MockFunction; ...@@ -263,7 +319,7 @@ class MockFunction;
$for i [[ $for i [[
$range j 0..i-1 $range j 0..i-1
$var ArgTypes = [[$for j, [[A$j]]]] $var ArgTypes = [[$for j, [[A$j]]]]
$var ArgNames = [[$for j, [[a$j]]]] $var ArgValues = [[$for j, [[::std::move(a$j)]]]]
$var ArgDecls = [[$for j, [[A$j a$j]]]] $var ArgDecls = [[$for j, [[A$j a$j]]]]
template <typename R$for j [[, typename A$j]]> template <typename R$for j [[, typename A$j]]>
class MockFunction<R($ArgTypes)> { class MockFunction<R($ArgTypes)> {
...@@ -273,9 +329,9 @@ class MockFunction<R($ArgTypes)> { ...@@ -273,9 +329,9 @@ class MockFunction<R($ArgTypes)> {
MOCK_METHOD$i[[]]_T(Call, R($ArgTypes)); MOCK_METHOD$i[[]]_T(Call, R($ArgTypes));
#if GTEST_HAS_STD_FUNCTION_ #if GTEST_HAS_STD_FUNCTION_
std::function<R($ArgTypes)> AsStdFunction() { ::std::function<R($ArgTypes)> AsStdFunction() {
return [this]($ArgDecls) -> R { return [this]($ArgDecls) -> R {
return this->Call($ArgNames); return this->Call($ArgValues);
}; };
} }
#endif // GTEST_HAS_STD_FUNCTION_ #endif // GTEST_HAS_STD_FUNCTION_
......
$$ -*- mode: c++; -*- $$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to $$ This is a Pump source file. Please use Pump to convert
$$ gmock-generated-actions.h. $$ it to gmock-generated-matchers.h.
$$ $$
$var n = 10 $$ The maximum arity we support. $var n = 10 $$ The maximum arity we support.
$$ }} This line fixes auto-indentation of the following code in Emacs. $$ }} This line fixes auto-indentation of the following code in Emacs.
...@@ -303,6 +303,9 @@ $for j, [[ ...@@ -303,6 +303,9 @@ $for j, [[
// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension // UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
// that matches n elements in any order. We support up to n=$n arguments. // that matches n elements in any order. We support up to n=$n arguments.
//
// If you have >$n elements, consider UnorderedElementsAreArray() or
// UnorderedPointwise() instead.
$range i 0..n $range i 0..n
$for i [[ $for i [[
...@@ -479,7 +482,7 @@ $$ // show up in the generated code. ...@@ -479,7 +482,7 @@ $$ // show up in the generated code.
// using testing::PrintToString; // using testing::PrintToString;
// //
// MATCHER_P2(InClosedRange, low, hi, // MATCHER_P2(InClosedRange, low, hi,
// string(negation ? "is not" : "is") + " in range [" + // std::string(negation ? "is not" : "is") + " in range [" +
// PrintToString(low) + ", " + PrintToString(hi) + "]") { // PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi; // return low <= arg && arg <= hi;
// } // }
...@@ -604,32 +607,34 @@ $var template = [[$if i==0 [[]] $else [[ ...@@ -604,32 +607,34 @@ $var template = [[$if i==0 [[]] $else [[
]]]] ]]]]
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] $var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] $var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] $var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::move(gmock_p$j))]]]]]]
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] $var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::move(gmock_p$j))]]]]]]
$var params = [[$for j, [[p$j]]]] $var params = [[$for j, [[p$j]]]]
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] $var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] $var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
$var param_field_decls = [[$for j $var param_field_decls = [[$for j
[[ [[
p$j##_type p$j;\ p$j##_type const p$j;\
]]]] ]]]]
$var param_field_decls2 = [[$for j $var param_field_decls2 = [[$for j
[[ [[
p$j##_type p$j;\ p$j##_type const p$j;\
]]]] ]]]]
#define $macro_name(name$for j [[, p$j]], description)\$template #define $macro_name(name$for j [[, p$j]], description)\$template
class $class_name {\ class $class_name {\
public:\ public:\
template <typename arg_type>\ template <typename arg_type>\
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\ class gmock_Impl : public ::testing::MatcherInterface<\
GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\ public:\
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\ [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
$impl_inits {}\ $impl_inits {}\
virtual bool MatchAndExplain(\ virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\ virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\ *gmock_os << FormatDescription(false);\
}\ }\
...@@ -637,17 +642,15 @@ $var param_field_decls2 = [[$for j ...@@ -637,17 +642,15 @@ $var param_field_decls2 = [[$for j
*gmock_os << FormatDescription(true);\ *gmock_os << FormatDescription(true);\
}\$param_field_decls }\$param_field_decls
private:\ private:\
::testing::internal::string FormatDescription(bool negation) const {\ ::std::string FormatDescription(bool negation) const {\
const ::testing::internal::string gmock_description = (description);\ ::std::string gmock_description = (description);\
if (!gmock_description.empty()) {\ if (!gmock_description.empty())\
return gmock_description;\ return gmock_description;\
}\
return ::testing::internal::FormatMatcherDescription(\ return ::testing::internal::FormatMatcherDescription(\
negation, #name, \ negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
::testing::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ ::testing::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
}\ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\ };\
template <typename arg_type>\ template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\ operator ::testing::Matcher<arg_type>() const {\
...@@ -657,14 +660,13 @@ $var param_field_decls2 = [[$for j ...@@ -657,14 +660,13 @@ $var param_field_decls2 = [[$for j
[[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\ [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\
}\$param_field_decls2 }\$param_field_decls2
private:\ private:\
GTEST_DISALLOW_ASSIGN_($class_name);\
};\$template };\$template
inline $class_name$param_types name($param_types_and_names) {\ inline $class_name$param_types name($param_types_and_names) {\
return $class_name$param_types($params);\ return $class_name$param_types($params);\
}\$template }\$template
template <typename arg_type>\ template <typename arg_type>\
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\ bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
arg_type arg, \ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const const
]] ]]
......
...@@ -51,10 +51,9 @@ ...@@ -51,10 +51,9 @@
// NiceMock<MockFoo>. // NiceMock<MockFoo>.
// //
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// their respective base class, with up-to 10 arguments. Therefore // their respective base class. Therefore you can write
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock // NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
// where MockFoo has a constructor that accepts (int, const char*), // has a constructor that accepts (int, const char*), for example.
// for example.
// //
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using // and StrictMock<MockFoo> only works for mock methods defined using
...@@ -63,10 +62,6 @@ ...@@ -63,10 +62,6 @@
// or "strict" modifier may not affect it, depending on the compiler. // or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported. // supported.
//
// Another known limitation is that the constructors of the base mock
// cannot have arguments passed by non-const reference, which are
// banned by the Google C++ style guide anyway.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
...@@ -79,15 +74,35 @@ namespace testing { ...@@ -79,15 +74,35 @@ namespace testing {
template <class MockClass> template <class MockClass>
class NiceMock : public MockClass { class NiceMock : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as NiceMock() : MockClass() {
// we have to avoid a possible clash with members of MockClass.
NiceMock() {
::testing::Mock::AllowUninterestingCalls( ::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have #if GTEST_LANG_CXX11
// to define it for each arity. // Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename... An>
NiceMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else
// C++98 doesn't have variadic templates, so we have to define one
// for each arity.
template <typename A1> template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) { explicit NiceMock(const A1& a1) : MockClass(a1) {
::testing::Mock::AllowUninterestingCalls( ::testing::Mock::AllowUninterestingCalls(
...@@ -163,7 +178,9 @@ class NiceMock : public MockClass { ...@@ -163,7 +178,9 @@ class NiceMock : public MockClass {
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
virtual ~NiceMock() { #endif // GTEST_LANG_CXX11
~NiceMock() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
...@@ -175,15 +192,35 @@ class NiceMock : public MockClass { ...@@ -175,15 +192,35 @@ class NiceMock : public MockClass {
template <class MockClass> template <class MockClass>
class NaggyMock : public MockClass { class NaggyMock : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as NaggyMock() : MockClass() {
// we have to avoid a possible clash with members of MockClass. ::testing::Mock::WarnUninterestingCalls(
NaggyMock() { internal::ImplicitCast_<MockClass*>(this));
}
#if GTEST_LANG_CXX11
// Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::WarnUninterestingCalls( ::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have template <typename A1, typename A2, typename... An>
// to define it for each arity. NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else
// C++98 doesn't have variadic templates, so we have to define one
// for each arity.
template <typename A1> template <typename A1>
explicit NaggyMock(const A1& a1) : MockClass(a1) { explicit NaggyMock(const A1& a1) : MockClass(a1) {
::testing::Mock::WarnUninterestingCalls( ::testing::Mock::WarnUninterestingCalls(
...@@ -259,7 +296,9 @@ class NaggyMock : public MockClass { ...@@ -259,7 +296,9 @@ class NaggyMock : public MockClass {
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
virtual ~NaggyMock() { #endif // GTEST_LANG_CXX11
~NaggyMock() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
...@@ -271,15 +310,35 @@ class NaggyMock : public MockClass { ...@@ -271,15 +310,35 @@ class NaggyMock : public MockClass {
template <class MockClass> template <class MockClass>
class StrictMock : public MockClass { class StrictMock : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as StrictMock() : MockClass() {
// we have to avoid a possible clash with members of MockClass. ::testing::Mock::FailUninterestingCalls(
StrictMock() { internal::ImplicitCast_<MockClass*>(this));
}
#if GTEST_LANG_CXX11
// Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::FailUninterestingCalls( ::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have template <typename A1, typename A2, typename... An>
// to define it for each arity. StrictMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else
// C++98 doesn't have variadic templates, so we have to define one
// for each arity.
template <typename A1> template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) { explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls( ::testing::Mock::FailUninterestingCalls(
...@@ -355,7 +414,9 @@ class StrictMock : public MockClass { ...@@ -355,7 +414,9 @@ class StrictMock : public MockClass {
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
virtual ~StrictMock() { #endif // GTEST_LANG_CXX11
~StrictMock() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
......
$$ -*- mode: c++; -*- $$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to $$ This is a Pump source file. Please use Pump to convert
$$ gmock-generated-nice-strict.h. $$ it to gmock-generated-nice-strict.h.
$$ $$
$var n = 10 $$ The maximum arity we support. $var n = 10 $$ The maximum arity we support.
// Copyright 2008, Google Inc. // Copyright 2008, Google Inc.
...@@ -52,10 +52,9 @@ $var n = 10 $$ The maximum arity we support. ...@@ -52,10 +52,9 @@ $var n = 10 $$ The maximum arity we support.
// NiceMock<MockFoo>. // NiceMock<MockFoo>.
// //
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// their respective base class, with up-to $n arguments. Therefore // their respective base class. Therefore you can write
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock // NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
// where MockFoo has a constructor that accepts (int, const char*), // has a constructor that accepts (int, const char*), for example.
// for example.
// //
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using // and StrictMock<MockFoo> only works for mock methods defined using
...@@ -64,10 +63,6 @@ $var n = 10 $$ The maximum arity we support. ...@@ -64,10 +63,6 @@ $var n = 10 $$ The maximum arity we support.
// or "strict" modifier may not affect it, depending on the compiler. // or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported. // supported.
//
// Another known limitation is that the constructors of the base mock
// cannot have arguments passed by non-const reference, which are
// banned by the Google C++ style guide anyway.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
...@@ -91,15 +86,35 @@ $var method=[[$if kind==0 [[AllowUninterestingCalls]] ...@@ -91,15 +86,35 @@ $var method=[[$if kind==0 [[AllowUninterestingCalls]]
template <class MockClass> template <class MockClass>
class $clazz : public MockClass { class $clazz : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as $clazz() : MockClass() {
// we have to avoid a possible clash with members of MockClass. ::testing::Mock::$method(
$clazz() { internal::ImplicitCast_<MockClass*>(this));
}
#if GTEST_LANG_CXX11
// Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit $clazz(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::$method( ::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have template <typename A1, typename A2, typename... An>
// to define it for each arity. $clazz(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
#else
// C++98 doesn't have variadic templates, so we have to define one
// for each arity.
template <typename A1> template <typename A1>
explicit $clazz(const A1& a1) : MockClass(a1) { explicit $clazz(const A1& a1) : MockClass(a1) {
::testing::Mock::$method( ::testing::Mock::$method(
...@@ -117,7 +132,9 @@ $range j 1..i ...@@ -117,7 +132,9 @@ $range j 1..i
]] ]]
virtual ~$clazz() { #endif // GTEST_LANG_CXX11
~$clazz() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
......
This diff is collapsed.
...@@ -43,6 +43,18 @@ ...@@ -43,6 +43,18 @@
namespace testing { namespace testing {
// Silence C4100 (unreferenced formal
// parameter) for MSVC
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#if (_MSC_VER == 1900)
// and silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 14
# pragma warning(disable:4800)
#endif
#endif
// Defines a matcher that matches an empty container. The container must // Defines a matcher that matches an empty container. The container must
// support both size() and empty(), which all STL-like containers provide. // support both size() and empty(), which all STL-like containers provide.
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
...@@ -69,6 +81,11 @@ MATCHER(IsFalse, negation ? "is true" : "is false") { ...@@ -69,6 +81,11 @@ MATCHER(IsFalse, negation ? "is true" : "is false") {
return !static_cast<bool>(arg); return !static_cast<bool>(arg);
} }
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace testing } // namespace testing
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_ #endif // GMOCK_GMOCK_MORE_MATCHERS_H_
...@@ -147,14 +147,13 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -147,14 +147,13 @@ class GTEST_API_ UntypedFunctionMockerBase {
// action fails. // action fails.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
const void* untyped_args, const std::string& call_description) const = 0; void* untyped_args, const std::string& call_description) const = 0;
// Performs the given action with the given arguments and returns // Performs the given action with the given arguments and returns
// the action's result. // the action's result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformAction( virtual UntypedActionResultHolderBase* UntypedPerformAction(
const void* untyped_action, const void* untyped_action, void* untyped_args) const = 0;
const void* untyped_args) const = 0;
// Writes a message that the call is uninteresting (i.e. neither // Writes a message that the call is uninteresting (i.e. neither
// explicitly expected nor explicitly unexpected) to the given // explicitly expected nor explicitly unexpected) to the given
...@@ -209,9 +208,8 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -209,9 +208,8 @@ class GTEST_API_ UntypedFunctionMockerBase {
// arguments. This function can be safely called from multiple // arguments. This function can be safely called from multiple
// threads concurrently. The caller is responsible for deleting the // threads concurrently. The caller is responsible for deleting the
// result. // result.
UntypedActionResultHolderBase* UntypedInvokeWith( UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args)
const void* untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
protected: protected:
typedef std::vector<const void*> UntypedOnCallSpecs; typedef std::vector<const void*> UntypedOnCallSpecs;
...@@ -236,6 +234,14 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -236,6 +234,14 @@ class GTEST_API_ UntypedFunctionMockerBase {
UntypedOnCallSpecs untyped_on_call_specs_; UntypedOnCallSpecs untyped_on_call_specs_;
// All expectations for this function mocker. // All expectations for this function mocker.
//
// It's undefined behavior to interleave expectations (EXPECT_CALLs
// or ON_CALLs) and mock function calls. Also, the order of
// expectations is important. Therefore it's a logic race condition
// to read/write untyped_expectations_ concurrently. In order for
// tools like tsan to catch concurrent read/write accesses to
// untyped_expectations, we deliberately leave accesses to it
// unprotected.
UntypedExpectations untyped_expectations_; UntypedExpectations untyped_expectations_;
}; // class UntypedFunctionMockerBase }; // class UntypedFunctionMockerBase
...@@ -1252,8 +1258,9 @@ class MockSpec { ...@@ -1252,8 +1258,9 @@ class MockSpec {
// Constructs a MockSpec object, given the function mocker object // Constructs a MockSpec object, given the function mocker object
// that the spec is associated with. // that the spec is associated with.
explicit MockSpec(internal::FunctionMockerBase<F>* function_mocker) MockSpec(internal::FunctionMockerBase<F>* function_mocker,
: function_mocker_(function_mocker) {} const ArgumentMatcherTuple& matchers)
: function_mocker_(function_mocker), matchers_(matchers) {}
// Adds a new default action spec to the function mocker and returns // Adds a new default action spec to the function mocker and returns
// the newly created spec. // the newly created spec.
...@@ -1275,14 +1282,17 @@ class MockSpec { ...@@ -1275,14 +1282,17 @@ class MockSpec {
file, line, source_text, matchers_); file, line, source_text, matchers_);
} }
// This operator overload is used to swallow the superfluous parameter list
// introduced by the ON/EXPECT_CALL macros. See the macro comments for more
// explanation.
MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) {
return *this;
}
private: private:
template <typename Function> template <typename Function>
friend class internal::FunctionMocker; friend class internal::FunctionMocker;
void SetMatchers(const ArgumentMatcherTuple& matchers) {
matchers_ = matchers;
}
// The function mocker that owns this spec. // The function mocker that owns this spec.
internal::FunctionMockerBase<F>* const function_mocker_; internal::FunctionMockerBase<F>* const function_mocker_;
// The argument matchers specified in the spec. // The argument matchers specified in the spec.
...@@ -1390,19 +1400,20 @@ class ActionResultHolder : public UntypedActionResultHolderBase { ...@@ -1390,19 +1400,20 @@ class ActionResultHolder : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformDefaultAction( static ActionResultHolder* PerformDefaultAction(
const FunctionMockerBase<F>* func_mocker, const FunctionMockerBase<F>* func_mocker,
const typename Function<F>::ArgumentTuple& args, typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) { const std::string& call_description) {
return new ActionResultHolder(Wrapper( return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
func_mocker->PerformDefaultAction(args, call_description))); internal::move(args), call_description)));
} }
// Performs the given action and returns the result in a new-ed // Performs the given action and returns the result in a new-ed
// ActionResultHolder. // ActionResultHolder.
template <typename F> template <typename F>
static ActionResultHolder* static ActionResultHolder* PerformAction(
PerformAction(const Action<F>& action, const Action<F>& action,
const typename Function<F>::ArgumentTuple& args) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) {
return new ActionResultHolder(Wrapper(action.Perform(args))); return new ActionResultHolder(
Wrapper(action.Perform(internal::move(args))));
} }
private: private:
...@@ -1430,9 +1441,9 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase { ...@@ -1430,9 +1441,9 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformDefaultAction( static ActionResultHolder* PerformDefaultAction(
const FunctionMockerBase<F>* func_mocker, const FunctionMockerBase<F>* func_mocker,
const typename Function<F>::ArgumentTuple& args, typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) { const std::string& call_description) {
func_mocker->PerformDefaultAction(args, call_description); func_mocker->PerformDefaultAction(internal::move(args), call_description);
return new ActionResultHolder; return new ActionResultHolder;
} }
...@@ -1441,8 +1452,8 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase { ...@@ -1441,8 +1452,8 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformAction( static ActionResultHolder* PerformAction(
const Action<F>& action, const Action<F>& action,
const typename Function<F>::ArgumentTuple& args) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) {
action.Perform(args); action.Perform(internal::move(args));
return new ActionResultHolder; return new ActionResultHolder;
} }
...@@ -1461,7 +1472,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1461,7 +1472,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
typedef typename Function<F>::ArgumentTuple ArgumentTuple; typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
FunctionMockerBase() : current_spec_(this) {} FunctionMockerBase() {}
// The destructor verifies that all expectations on this mock // The destructor verifies that all expectations on this mock
// function have been satisfied. If not, it will report Google Test // function have been satisfied. If not, it will report Google Test
...@@ -1497,12 +1508,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1497,12 +1508,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// mutable state of this object, and thus can be called concurrently // mutable state of this object, and thus can be called concurrently
// without locking. // without locking.
// L = * // L = *
Result PerformDefaultAction(const ArgumentTuple& args, Result PerformDefaultAction(
const std::string& call_description) const { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) const {
const OnCallSpec<F>* const spec = const OnCallSpec<F>* const spec =
this->FindOnCallSpec(args); this->FindOnCallSpec(args);
if (spec != NULL) { if (spec != NULL) {
return spec->GetAction().Perform(args); return spec->GetAction().Perform(internal::move(args));
} }
const std::string message = const std::string message =
call_description + call_description +
...@@ -1524,11 +1536,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1524,11 +1536,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// action fails. The caller is responsible for deleting the result. // action fails. The caller is responsible for deleting the result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
const void* untyped_args, // must point to an ArgumentTuple void* untyped_args, // must point to an ArgumentTuple
const std::string& call_description) const { const std::string& call_description) const {
const ArgumentTuple& args = ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
*static_cast<const ArgumentTuple*>(untyped_args); return ResultHolder::PerformDefaultAction(this, internal::move(*args),
return ResultHolder::PerformDefaultAction(this, args, call_description); call_description);
} }
// Performs the given action with the given arguments and returns // Performs the given action with the given arguments and returns
...@@ -1536,13 +1548,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1536,13 +1548,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// result. // result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformAction( virtual UntypedActionResultHolderBase* UntypedPerformAction(
const void* untyped_action, const void* untyped_args) const { const void* untyped_action, void* untyped_args) const {
// Make a copy of the action before performing it, in case the // Make a copy of the action before performing it, in case the
// action deletes the mock object (and thus deletes itself). // action deletes the mock object (and thus deletes itself).
const Action<F> action = *static_cast<const Action<F>*>(untyped_action); const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
const ArgumentTuple& args = ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
*static_cast<const ArgumentTuple*>(untyped_args); return ResultHolder::PerformAction(action, internal::move(*args));
return ResultHolder::PerformAction(action, args);
} }
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
...@@ -1582,10 +1593,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1582,10 +1593,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Returns the result of invoking this mock function with the given // Returns the result of invoking this mock function with the given
// arguments. This function can be safely called from multiple // arguments. This function can be safely called from multiple
// threads concurrently. // threads concurrently.
Result InvokeWith(const ArgumentTuple& args) Result InvokeWith(
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
// const_cast is required since in C++98 we still pass ArgumentTuple around
// by const& instead of rvalue reference.
void* untyped_args = const_cast<void*>(static_cast<const void*>(&args));
scoped_ptr<ResultHolder> holder( scoped_ptr<ResultHolder> holder(
DownCast_<ResultHolder*>(this->UntypedInvokeWith(&args))); DownCast_<ResultHolder*>(this->UntypedInvokeWith(untyped_args)));
return holder->Unwrap(); return holder->Unwrap();
} }
...@@ -1609,6 +1624,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1609,6 +1624,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
TypedExpectation<F>* const expectation = TypedExpectation<F>* const expectation =
new TypedExpectation<F>(this, file, line, source_text, m); new TypedExpectation<F>(this, file, line, source_text, m);
const linked_ptr<ExpectationBase> untyped_expectation(expectation); const linked_ptr<ExpectationBase> untyped_expectation(expectation);
// See the definition of untyped_expectations_ for why access to
// it is unprotected here.
untyped_expectations_.push_back(untyped_expectation); untyped_expectations_.push_back(untyped_expectation);
// Adds this expectation into the implicit sequence if there is one. // Adds this expectation into the implicit sequence if there is one.
...@@ -1620,10 +1637,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1620,10 +1637,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
return *expectation; return *expectation;
} }
// The current spec (either default action spec or expectation spec)
// being described on this function mocker.
MockSpec<F>& current_spec() { return current_spec_; }
private: private:
template <typename Func> friend class TypedExpectation; template <typename Func> friend class TypedExpectation;
...@@ -1716,6 +1729,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1716,6 +1729,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
const ArgumentTuple& args) const const ArgumentTuple& args) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
// See the definition of untyped_expectations_ for why access to
// it is unprotected here.
for (typename UntypedExpectations::const_reverse_iterator it = for (typename UntypedExpectations::const_reverse_iterator it =
untyped_expectations_.rbegin(); untyped_expectations_.rbegin();
it != untyped_expectations_.rend(); ++it) { it != untyped_expectations_.rend(); ++it) {
...@@ -1766,10 +1781,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1766,10 +1781,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
} }
} }
// The current spec (either default action spec or expectation spec)
// being described on this function mocker.
MockSpec<F> current_spec_;
// There is no generally useful and implementable semantics of // There is no generally useful and implementable semantics of
// copying a mock object, so copying a mock is usually a user error. // copying a mock object, so copying a mock is usually a user error.
// Thus we disallow copying function mockers. If the user really // Thus we disallow copying function mockers. If the user really
...@@ -1832,17 +1843,76 @@ inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT ...@@ -1832,17 +1843,76 @@ inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT
} // namespace testing } // namespace testing
// A separate macro is required to avoid compile errors when the name // Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is
// of the method used in call is a result of macro expansion. // required to avoid compile errors when the name of the method used in call is
// See CompilesWithMethodNameExpandedFromMacro tests in // a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro
// internal/gmock-spec-builders_test.cc for more details. // tests in internal/gmock-spec-builders_test.cc for more details.
#define GMOCK_ON_CALL_IMPL_(obj, call) \ //
((obj).gmock_##call).InternalDefaultActionSetAt(__FILE__, __LINE__, \ // This macro supports statements both with and without parameter matchers. If
#obj, #call) // the parameter list is omitted, gMock will accept any parameters, which allows
#define ON_CALL(obj, call) GMOCK_ON_CALL_IMPL_(obj, call) // tests to be written that don't need to encode the number of method
// parameter. This technique may only be used for non-overloaded methods.
#define GMOCK_EXPECT_CALL_IMPL_(obj, call) \ //
((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call) // // These are the same:
#define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call) // ON_CALL(mock, NoArgsMethod()).WillByDefault(…);
// ON_CALL(mock, NoArgsMethod).WillByDefault(…);
//
// // As are these:
// ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(…);
// ON_CALL(mock, TwoArgsMethod).WillByDefault(…);
//
// // Can also specify args if you want, of course:
// ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(…);
//
// // Overloads work as long as you specify parameters:
// ON_CALL(mock, OverloadedMethod(_)).WillByDefault(…);
// ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(…);
//
// // Oops! Which overload did you want?
// ON_CALL(mock, OverloadedMethod).WillByDefault(…);
// => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous
//
// How this works: The mock class uses two overloads of the gmock_Method
// expectation setter method plus an operator() overload on the MockSpec object.
// In the matcher list form, the macro expands to:
//
// // This statement:
// ON_CALL(mock, TwoArgsMethod(_, 45))…
//
// // …expands to:
// mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)…
// |-------------v---------------||------------v-------------|
// invokes first overload swallowed by operator()
//
// // …which is essentially:
// mock.gmock_TwoArgsMethod(_, 45)…
//
// Whereas the form without a matcher list:
//
// // This statement:
// ON_CALL(mock, TwoArgsMethod)…
//
// // …expands to:
// mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)…
// |-----------------------v--------------------------|
// invokes second overload
//
// // …which is essentially:
// mock.gmock_TwoArgsMethod(_, _)…
//
// The WithoutMatchers() argument is used to disambiguate overloads and to
// block the caller from accidentally invoking the second overload directly. The
// second argument is an internal type derived from the method signature. The
// failure to disambiguate two overloads of this method in the ON_CALL statement
// is how we block callers from setting expectations on overloaded methods.
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), NULL) \
.Setter(__FILE__, __LINE__, #mock_expr, #call)
#define ON_CALL(obj, call) \
GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call)
#define EXPECT_CALL(obj, call) \
GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
$$ -*- mode: c++; -*- $$ -*- mode: c++; -*-
$$ This is a Pump source file (http://go/pump). Please use Pump to convert $$ This is a Pump source file. Please use Pump to convert
$$ it to callback-actions.h. $$ it to callback-actions.h.
$$ $$
$var max_callback_arity = 5 $var max_callback_arity = 5
......
...@@ -48,6 +48,14 @@ ...@@ -48,6 +48,14 @@
namespace testing { namespace testing {
namespace internal { namespace internal {
// Silence MSVC C4100 (unreferenced formal parameter) and
// C4805('==': unsafe mix of type 'const int' and type 'const bool')
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
# pragma warning(disable:4805)
#endif
// Joins a vector of strings as if they are fields of a tuple; returns // Joins a vector of strings as if they are fields of a tuple; returns
// the joined string. // the joined string.
GTEST_API_ std::string JoinAsTuple(const Strings& fields); GTEST_API_ std::string JoinAsTuple(const Strings& fields);
...@@ -336,6 +344,21 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity); ...@@ -336,6 +344,21 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity);
GTEST_API_ void Log(LogSeverity severity, const std::string& message, GTEST_API_ void Log(LogSeverity severity, const std::string& message,
int stack_frames_to_skip); int stack_frames_to_skip);
// A marker class that is used to resolve parameterless expectations to the
// correct overload. This must not be instantiable, to prevent client code from
// accidentally resolving to the overload; for example:
//
// ON_CALL(mock, Method({}, nullptr))…
//
class WithoutMatchers {
private:
WithoutMatchers() {}
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
};
// Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers();
// TODO(wan@google.com): group all type utilities together. // TODO(wan@google.com): group all type utilities together.
// Type traits. // Type traits.
...@@ -510,7 +533,7 @@ struct BooleanConstant {}; ...@@ -510,7 +533,7 @@ struct BooleanConstant {};
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to // Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
// reduce code size. // reduce code size.
void IllegalDoDefault(const char* file, int line); GTEST_API_ void IllegalDoDefault(const char* file, int line);
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// Helper types for Apply() below. // Helper types for Apply() below.
...@@ -539,6 +562,12 @@ auto Apply(F&& f, Tuple&& args) ...@@ -539,6 +562,12 @@ auto Apply(F&& f, Tuple&& args)
make_int_pack<std::tuple_size<Tuple>::value>()); make_int_pack<std::tuple_size<Tuple>::value>());
} }
#endif #endif
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
......
...@@ -188,7 +188,9 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message, ...@@ -188,7 +188,9 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
std::cout << ::std::flush; std::cout << ::std::flush;
} }
void IllegalDoDefault(const char* file, int line) { GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
GTEST_API_ void IllegalDoDefault(const char* file, int line) {
internal::Assert( internal::Assert(
false, file, line, false, file, line,
"You are using DoDefault() inside a composite action like " "You are using DoDefault() inside a composite action like "
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment