aboutsummaryrefslogtreecommitdiff
path: root/googlemock/include/gmock/gmock-spec-builders.h
diff options
context:
space:
mode:
Diffstat (limited to 'googlemock/include/gmock/gmock-spec-builders.h')
-rw-r--r--googlemock/include/gmock/gmock-spec-builders.h666
1 files changed, 389 insertions, 277 deletions
diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h
index f1bd79cf..78ca15d0 100644
--- a/googlemock/include/gmock/gmock-spec-builders.h
+++ b/googlemock/include/gmock/gmock-spec-builders.h
@@ -27,7 +27,6 @@
// (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 implements the ON_CALL() and EXPECT_CALL() macros.
@@ -56,20 +55,24 @@
// where all clauses are optional, and .InSequence()/.After()/
// .WillOnce() can appear any number of times.
-// GOOGLETEST_CM0002 DO NOT DELETE
+// IWYU pragma: private, include "gmock/gmock.h"
+// IWYU pragma: friend gmock/.*
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
+#include <cstdint>
#include <functional>
#include <map>
#include <memory>
+#include <ostream>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
+
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-matchers.h"
@@ -78,7 +81,7 @@
#include "gtest/gtest.h"
#if GTEST_HAS_EXCEPTIONS
-# include <stdexcept> // NOLINT
+#include <stdexcept> // NOLINT
#endif
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
@@ -97,13 +100,15 @@ class ExpectationSet;
namespace internal {
// Implements a mock function.
-template <typename F> class FunctionMocker;
+template <typename F>
+class FunctionMocker;
// Base class for expectations.
class ExpectationBase;
// Implements an expectation.
-template <typename F> class TypedExpectation;
+template <typename F>
+class TypedExpectation;
// Helper class for testing the Expectation class template.
class ExpectationTester;
@@ -129,9 +134,6 @@ class NaggyMockImpl;
// calls to ensure the integrity of the mock objects' states.
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);
-// Untyped base class for ActionResultHolder<R>.
-class UntypedActionResultHolderBase;
-
// Abstract base class of FunctionMocker. This is the
// type-agnostic part of the function mocker interface. Its pure
// virtual methods are implemented by FunctionMocker.
@@ -154,27 +156,12 @@ class GTEST_API_ UntypedFunctionMockerBase {
// responsibility to guarantee the correctness of the arguments'
// types.
- // Performs the default action with the given arguments and returns
- // the action's result. The call description string will be used in
- // the error message to describe the call in the case the default
- // action fails.
- // L = *
- virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
- void* untyped_args, const std::string& call_description) const = 0;
-
- // Performs the given action with the given arguments and returns
- // the action's result.
- // L = *
- virtual UntypedActionResultHolderBase* UntypedPerformAction(
- const void* untyped_action, void* untyped_args) const = 0;
-
// Writes a message that the call is uninteresting (i.e. neither
// explicitly expected nor explicitly unexpected) to the given
// ostream.
- virtual void UntypedDescribeUninterestingCall(
- const void* untyped_args,
- ::std::ostream* os) const
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
+ virtual void UntypedDescribeUninterestingCall(const void* untyped_args,
+ ::std::ostream* os) const
+ GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
// Returns the expectation that matches the given function arguments
// (or NULL is there's no match); when a match is found,
@@ -183,10 +170,9 @@ class GTEST_API_ UntypedFunctionMockerBase {
// is_excessive is modified to indicate whether the call exceeds the
// expected number.
virtual const ExpectationBase* UntypedFindMatchingExpectation(
- const void* untyped_args,
- const void** untyped_action, bool* is_excessive,
+ const void* untyped_args, const void** untyped_action, bool* is_excessive,
::std::ostream* what, ::std::ostream* why)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
+ GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
// Prints the given function arguments to the ostream.
virtual void UntypedPrintArgs(const void* untyped_args,
@@ -196,8 +182,7 @@ class GTEST_API_ UntypedFunctionMockerBase {
// this information in the global mock registry. Will be called
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
// method.
- void RegisterOwner(const void* mock_obj)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+ void RegisterOwner(const void* mock_obj) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
// Sets the mock object this mock method belongs to, and sets the
// name of the mock function. Will be called upon each invocation
@@ -208,26 +193,20 @@ class GTEST_API_ UntypedFunctionMockerBase {
// Returns the mock object this mock method belongs to. Must be
// called after RegisterOwner() or SetOwnerAndName() has been
// called.
- const void* MockObject() const
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+ const void* MockObject() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
// Returns the name of this mock method. Must be called after
// SetOwnerAndName() has been called.
- const char* Name() const
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
-
- // Returns the result of invoking this mock function with the given
- // arguments. This function can be safely called from multiple
- // threads concurrently. The caller is responsible for deleting the
- // result.
- UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+ const char* Name() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
protected:
typedef std::vector<const void*> UntypedOnCallSpecs;
using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;
+ struct UninterestingCallCleanupHandler;
+ struct FailureCleanupHandler;
+
// Returns an Expectation object that references and co-owns exp,
// which must be an expectation on this mock function.
Expectation GetHandleOf(ExpectationBase* exp);
@@ -430,29 +409,28 @@ class GTEST_API_ Mock {
// Tells Google Mock to allow uninteresting calls on the given mock
// object.
- static void AllowUninterestingCalls(const void* mock_obj)
+ static void AllowUninterestingCalls(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Tells Google Mock to warn the user about uninteresting calls on
// the given mock object.
- static void WarnUninterestingCalls(const void* mock_obj)
+ static void WarnUninterestingCalls(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Tells Google Mock to fail uninteresting calls on the given mock
// object.
- static void FailUninterestingCalls(const void* mock_obj)
+ static void FailUninterestingCalls(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Tells Google Mock the given mock object is being destroyed and
// its entry in the call-reaction table should be removed.
- static void UnregisterCallReaction(const void* mock_obj)
+ static void UnregisterCallReaction(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Returns the reaction Google Mock will have on uninteresting calls
// made on the given mock object.
static internal::CallReaction GetReactionOnUninterestingCalls(
- const void* mock_obj)
- GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+ const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Verifies that all expectations on the given mock object have been
// satisfied. Reports one or more Google Test non-fatal failures
@@ -465,17 +443,16 @@ class GTEST_API_ Mock {
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
// Registers a mock object and a mock method it owns.
- static void Register(
- const void* mock_obj,
- internal::UntypedFunctionMockerBase* mocker)
- GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+ static void Register(const void* mock_obj,
+ internal::UntypedFunctionMockerBase* mocker)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Tells Google Mock where in the source code mock_obj is used in an
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
// information helps the user identify which object it is.
- static void RegisterUseByOnCallOrExpectCall(
- const void* mock_obj, const char* file, int line)
- GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+ static void RegisterUseByOnCallOrExpectCall(const void* mock_obj,
+ const char* file, int line)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Unregisters a mock method; removes the owning mock object from
// the registry when the last mock method associated with it has
@@ -589,7 +566,7 @@ class ExpectationSet {
typedef Expectation::Set::value_type value_type;
// Constructs an empty set.
- ExpectationSet() {}
+ ExpectationSet() = default;
// This single-argument ctor must not be explicit, in order to support the
// ExpectationSet es = EXPECT_CALL(...);
@@ -632,7 +609,6 @@ class ExpectationSet {
Expectation::Set expectations_;
};
-
// Sequence objects are used by a user to specify the relative order
// in which the expectations should match. They are copyable (we rely
// on the compiler-defined copy constructor and assignment operator).
@@ -678,11 +654,13 @@ class GTEST_API_ InSequence {
public:
InSequence();
~InSequence();
+
private:
bool sequence_created_;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence); // NOLINT
-} GTEST_ATTRIBUTE_UNUSED_;
+ InSequence(const InSequence&) = delete;
+ InSequence& operator=(const InSequence&) = delete;
+};
namespace internal {
@@ -732,6 +710,12 @@ class GTEST_API_ ExpectationBase {
// describes it to the ostream.
virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0;
+ // Do not rely on this for correctness.
+ // This is only for making human-readable test output easier to understand.
+ void UntypedDescription(std::string description) {
+ description_ = std::move(description);
+ }
+
protected:
friend class ::testing::Expectation;
friend class UntypedFunctionMockerBase;
@@ -784,40 +768,38 @@ class GTEST_API_ ExpectationBase {
// the current thread.
// Retires all pre-requisites of this expectation.
- void RetireAllPreRequisites()
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
+ void RetireAllPreRequisites() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
// Returns true if and only if this expectation is retired.
- bool is_retired() const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ bool is_retired() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return retired_;
}
// Retires this expectation.
- void Retire()
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ void Retire() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
retired_ = true;
}
+ // Returns a human-readable description of this expectation.
+ // Do not rely on this for correctness. It is only for human readability.
+ const std::string& GetDescription() const { return description_; }
+
// Returns true if and only if this expectation is satisfied.
- bool IsSatisfied() const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ bool IsSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return cardinality().IsSatisfiedByCallCount(call_count_);
}
// Returns true if and only if this expectation is saturated.
- bool IsSaturated() const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ bool IsSaturated() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return cardinality().IsSaturatedByCallCount(call_count_);
}
// Returns true if and only if this expectation is over-saturated.
- bool IsOverSaturated() const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ bool IsOverSaturated() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return cardinality().IsOverSaturatedByCallCount(call_count_);
}
@@ -832,15 +814,13 @@ class GTEST_API_ ExpectationBase {
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
// Returns the number this expectation has been invoked.
- int call_count() const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ int call_count() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return call_count_;
}
// Increments the number this expectation has been invoked.
- void IncrementCallCount()
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ void IncrementCallCount() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
call_count_++;
}
@@ -849,8 +829,7 @@ class GTEST_API_ ExpectationBase {
// WillRepeatedly() clauses) against the cardinality if this hasn't
// been done before. Prints a warning if there are too many or too
// few actions.
- void CheckActionCountIfNotDone() const
- GTEST_LOCK_EXCLUDED_(mutex_);
+ void CheckActionCountIfNotDone() const GTEST_LOCK_EXCLUDED_(mutex_);
friend class ::testing::Sequence;
friend class ::testing::internal::ExpectationTester;
@@ -863,12 +842,13 @@ class GTEST_API_ ExpectationBase {
// This group of fields are part of the spec and won't change after
// an EXPECT_CALL() statement finishes.
- const char* file_; // The file that contains the expectation.
- int line_; // The line number of the expectation.
+ const char* file_; // The file that contains the expectation.
+ int line_; // The line number of the expectation.
const std::string source_text_; // The EXPECT_CALL(...) source text.
+ std::string description_; // User-readable name for the expectation.
// True if and only if the cardinality is specified explicitly.
bool cardinality_specified_;
- Cardinality cardinality_; // The cardinality of the expectation.
+ Cardinality cardinality_; // The cardinality of the expectation.
// The immediate pre-requisites (i.e. expectations that must be
// satisfied before this expectation can be matched) of this
// expectation. We use std::shared_ptr in the set because we want an
@@ -887,12 +867,18 @@ class GTEST_API_ ExpectationBase {
bool retires_on_saturation_;
Clause last_clause_;
mutable bool action_count_checked_; // Under mutex_.
- mutable Mutex mutex_; // Protects action_count_checked_.
-}; // class ExpectationBase
+ mutable Mutex mutex_; // Protects action_count_checked_.
+}; // class ExpectationBase
-// Impements an expectation for the given function type.
template <typename F>
-class TypedExpectation : public ExpectationBase {
+class TypedExpectation;
+
+// Implements an expectation for the given function type.
+template <typename R, typename... Args>
+class TypedExpectation<R(Args...)> : public ExpectationBase {
+ private:
+ using F = R(Args...);
+
public:
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
@@ -938,6 +924,13 @@ class TypedExpectation : public ExpectationBase {
return *this;
}
+ // Do not rely on this for correctness.
+ // This is only for making human-readable test output easier to understand.
+ TypedExpectation& Description(std::string name) {
+ ExpectationBase::UntypedDescription(std::move(name));
+ return *this;
+ }
+
// Implements the .Times() clause.
TypedExpectation& Times(const Cardinality& a_cardinality) {
ExpectationBase::UntypedTimes(a_cardinality);
@@ -945,9 +938,7 @@ class TypedExpectation : public ExpectationBase {
}
// Implements the .Times() clause.
- TypedExpectation& Times(int n) {
- return Times(Exactly(n));
- }
+ TypedExpectation& Times(int n) { return Times(Exactly(n)); }
// Implements the .InSequence() clause.
TypedExpectation& InSequence(const Sequence& s) {
@@ -1007,14 +998,31 @@ class TypedExpectation : public ExpectationBase {
return After(s1, s2, s3, s4).After(s5);
}
- // Implements the .WillOnce() clause.
- TypedExpectation& WillOnce(const Action<F>& action) {
+ // Preferred, type-safe overload: consume anything that can be directly
+ // converted to a OnceAction, except for Action<F> objects themselves.
+ TypedExpectation& WillOnce(OnceAction<F> once_action) {
+ // Call the overload below, smuggling the OnceAction as a copyable callable.
+ // We know this is safe because a WillOnce action will not be called more
+ // than once.
+ return WillOnce(Action<F>(ActionAdaptor{
+ std::make_shared<OnceAction<F>>(std::move(once_action)),
+ }));
+ }
+
+ // Fallback overload: accept Action<F> objects and those actions that define
+ // `operator Action<F>` but not `operator OnceAction<F>`.
+ //
+ // This is templated in order to cause the overload above to be preferred
+ // when the input is convertible to either type.
+ template <int&... ExplicitArgumentBarrier, typename = void>
+ TypedExpectation& WillOnce(Action<F> action) {
ExpectSpecProperty(last_clause_ <= kWillOnce,
".WillOnce() cannot appear after "
".WillRepeatedly() or .RetiresOnSaturation().");
last_clause_ = kWillOnce;
- untyped_actions_.push_back(new Action<F>(action));
+ untyped_actions_.push_back(new Action<F>(std::move(action)));
+
if (!cardinality_specified()) {
set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));
}
@@ -1062,9 +1070,7 @@ class TypedExpectation : public ExpectationBase {
// Returns the matchers for the arguments as specified inside the
// EXPECT_CALL() macro.
- const ArgumentMatcherTuple& matchers() const {
- return matchers_;
- }
+ const ArgumentMatcherTuple& matchers() const { return matchers_; }
// Returns the matcher specified by the .With() clause.
const Matcher<const ArgumentTuple&>& extra_matcher() const {
@@ -1088,6 +1094,16 @@ class TypedExpectation : public ExpectationBase {
template <typename Function>
friend class FunctionMocker;
+ // An adaptor that turns a OneAction<F> into something compatible with
+ // Action<F>. Must be called at most once.
+ struct ActionAdaptor {
+ std::shared_ptr<OnceAction<R(Args...)>> once_action;
+
+ R operator()(Args&&... args) const {
+ return std::move(*once_action).Call(std::forward<Args>(args)...);
+ }
+ };
+
// Returns an Expectation object that references and co-owns this
// expectation.
Expectation GetHandle() override { return owner_->GetHandleOf(this); }
@@ -1119,10 +1135,8 @@ class TypedExpectation : public ExpectationBase {
// Describes the result of matching the arguments against this
// expectation to the given ostream.
- void ExplainMatchResultTo(
- const ArgumentTuple& args,
- ::std::ostream* os) const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ void ExplainMatchResultTo(const ArgumentTuple& args, ::std::ostream* os) const
+ GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
if (is_retired()) {
@@ -1181,9 +1195,9 @@ class TypedExpectation : public ExpectationBase {
::std::stringstream ss;
DescribeLocationTo(&ss);
ss << "Actions ran out in " << source_text() << "...\n"
- << "Called " << count << " times, but only "
- << action_count << " WillOnce()"
- << (action_count == 1 ? " is" : "s are") << " specified - ";
+ << "Called " << count << " times, but only " << action_count
+ << " WillOnce()" << (action_count == 1 ? " is" : "s are")
+ << " specified - ";
mocker->DescribeDefaultActionTo(args, &ss);
Log(kWarning, ss.str(), 1);
}
@@ -1207,10 +1221,15 @@ class TypedExpectation : public ExpectationBase {
::std::ostream* why)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
+ const ::std::string& expectation_description = GetDescription();
if (IsSaturated()) {
// We have an excessive call.
IncrementCallCount();
- *what << "Mock function called more times than expected - ";
+ *what << "Mock function ";
+ if (!expectation_description.empty()) {
+ *what << "\"" << expectation_description << "\" ";
+ }
+ *what << "called more times than expected - ";
mocker->DescribeDefaultActionTo(args, what);
DescribeCallCountTo(why);
@@ -1225,7 +1244,11 @@ class TypedExpectation : public ExpectationBase {
}
// Must be done after IncrementCount()!
- *what << "Mock function call matches " << source_text() <<"...\n";
+ *what << "Mock function ";
+ if (!expectation_description.empty()) {
+ *what << "\"" << expectation_description << "\" ";
+ }
+ *what << "call matches " << source_text() << "...\n";
return &(GetCurrentAction(mocker, args));
}
@@ -1236,7 +1259,8 @@ class TypedExpectation : public ExpectationBase {
Matcher<const ArgumentTuple&> extra_matcher_;
Action<F> repeated_action_;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(TypedExpectation);
+ TypedExpectation(const TypedExpectation&) = delete;
+ TypedExpectation& operator=(const TypedExpectation&) = delete;
}; // class TypedExpectation
// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for
@@ -1258,8 +1282,8 @@ template <typename F>
class MockSpec {
public:
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
- typedef typename internal::Function<F>::ArgumentMatcherTuple
- ArgumentMatcherTuple;
+ typedef
+ typename internal::Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
// Constructs a MockSpec object, given the function mocker object
// that the spec is associated with.
@@ -1269,8 +1293,9 @@ class MockSpec {
// Adds a new default action spec to the function mocker and returns
// the newly created spec.
- internal::OnCallSpec<F>& InternalDefaultActionSetAt(
- const char* file, int line, const char* obj, const char* call) {
+ internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,
+ int line, const char* obj,
+ const char* call) {
LogWithLocation(internal::kInfo, file, line,
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
@@ -1278,13 +1303,14 @@ class MockSpec {
// Adds a new expectation spec to the function mocker and returns
// the newly created spec.
- internal::TypedExpectation<F>& InternalExpectedAt(
- const char* file, int line, const char* obj, const char* call) {
+ internal::TypedExpectation<F>& InternalExpectedAt(const char* file, int line,
+ const char* obj,
+ const char* call) {
const std::string source_text(std::string("EXPECT_CALL(") + obj + ", " +
call + ")");
LogWithLocation(internal::kInfo, file, line, source_text + " invoked");
- return function_mocker_->AddNewExpectation(
- file, line, source_text, matchers_);
+ return function_mocker_->AddNewExpectation(file, line, source_text,
+ matchers_);
}
// This operator overload is used to swallow the superfluous parameter list
@@ -1317,9 +1343,7 @@ template <typename T>
class ReferenceOrValueWrapper {
public:
// Constructs a wrapper from the given value/reference.
- explicit ReferenceOrValueWrapper(T value)
- : value_(std::move(value)) {
- }
+ explicit ReferenceOrValueWrapper(T value) : value_(std::move(value)) {}
// Unwraps and returns the underlying value/reference, exactly as
// originally passed. The behavior of calling this more than once on
@@ -1330,9 +1354,7 @@ class ReferenceOrValueWrapper {
// Always returns a const reference (more precisely,
// const std::add_lvalue_reference<T>::type). The behavior of calling this
// after calling Unwrap on the same object is unspecified.
- const T& Peek() const {
- return value_;
- }
+ const T& Peek() const { return value_; }
private:
T value_;
@@ -1346,8 +1368,7 @@ class ReferenceOrValueWrapper<T&> {
// Workaround for debatable pass-by-reference lint warning (c-library-team
// policy precludes NOLINT in this context)
typedef T& reference;
- explicit ReferenceOrValueWrapper(reference ref)
- : value_ptr_(&ref) {}
+ explicit ReferenceOrValueWrapper(reference ref) : value_ptr_(&ref) {}
T& Unwrap() { return *value_ptr_; }
const T& Peek() const { return *value_ptr_; }
@@ -1355,102 +1376,62 @@ class ReferenceOrValueWrapper<T&> {
T* value_ptr_;
};
-// C++ treats the void type specially. For example, you cannot define
-// a void-typed variable or pass a void value to a function.
-// ActionResultHolder<T> holds a value of type T, where T must be a
-// copyable type or void (T doesn't need to be default-constructable).
-// It hides the syntactic difference between void and other types, and
-// is used to unify the code for invoking both void-returning and
-// non-void-returning mock functions.
-
-// Untyped base class for ActionResultHolder<T>.
-class UntypedActionResultHolderBase {
- public:
- virtual ~UntypedActionResultHolderBase() {}
-
- // Prints the held value as an action's result to os.
- virtual void PrintAsActionResult(::std::ostream* os) const = 0;
-};
-
-// This generic definition is used when T is not void.
+// Prints the held value as an action's result to os.
template <typename T>
-class ActionResultHolder : public UntypedActionResultHolderBase {
- public:
- // Returns the held value. Must not be called more than once.
- T Unwrap() {
- return result_.Unwrap();
- }
-
- // Prints the held value as an action's result to os.
- void PrintAsActionResult(::std::ostream* os) const override {
- *os << "\n Returns: ";
- // T may be a reference type, so we don't use UniversalPrint().
- UniversalPrinter<T>::Print(result_.Peek(), os);
- }
+void PrintAsActionResult(const T& result, std::ostream& os) {
+ os << "\n Returns: ";
+ // T may be a reference type, so we don't use UniversalPrint().
+ UniversalPrinter<T>::Print(result, &os);
+}
- // Performs the given mock function's default action and returns the
- // result in a new-ed ActionResultHolder.
- template <typename F>
- static ActionResultHolder* PerformDefaultAction(
- const FunctionMocker<F>* func_mocker,
- typename Function<F>::ArgumentTuple&& args,
- const std::string& call_description) {
- return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
- std::move(args), call_description)));
- }
+// Reports an uninteresting call (whose description is in msg) in the
+// manner specified by 'reaction'.
+GTEST_API_ void ReportUninterestingCall(CallReaction reaction,
+ const std::string& msg);
- // Performs the given action and returns the result in a new-ed
- // ActionResultHolder.
- template <typename F>
- static ActionResultHolder* PerformAction(
- const Action<F>& action, typename Function<F>::ArgumentTuple&& args) {
- return new ActionResultHolder(
- Wrapper(action.Perform(std::move(args))));
- }
+// A generic RAII type that runs a user-provided function in its destructor.
+class Cleanup final {
+ public:
+ explicit Cleanup(std::function<void()> f) : f_(std::move(f)) {}
+ ~Cleanup() { f_(); }
private:
- typedef ReferenceOrValueWrapper<T> Wrapper;
-
- explicit ActionResultHolder(Wrapper result)
- : result_(std::move(result)) {
- }
-
- Wrapper result_;
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
+ std::function<void()> f_;
};
-// Specialization for T = void.
-template <>
-class ActionResultHolder<void> : public UntypedActionResultHolderBase {
- public:
- void Unwrap() { }
-
- void PrintAsActionResult(::std::ostream* /* os */) const override {}
+struct UntypedFunctionMockerBase::UninterestingCallCleanupHandler {
+ CallReaction reaction;
+ std::stringstream& ss;
- // Performs the given mock function's default action and returns ownership
- // of an empty ActionResultHolder*.
- template <typename F>
- static ActionResultHolder* PerformDefaultAction(
- const FunctionMocker<F>* func_mocker,
- typename Function<F>::ArgumentTuple&& args,
- const std::string& call_description) {
- func_mocker->PerformDefaultAction(std::move(args), call_description);
- return new ActionResultHolder;
+ ~UninterestingCallCleanupHandler() {
+ ReportUninterestingCall(reaction, ss.str());
}
+};
- // Performs the given action and returns ownership of an empty
- // ActionResultHolder*.
- template <typename F>
- static ActionResultHolder* PerformAction(
- const Action<F>& action, typename Function<F>::ArgumentTuple&& args) {
- action.Perform(std::move(args));
- return new ActionResultHolder;
+struct UntypedFunctionMockerBase::FailureCleanupHandler {
+ std::stringstream& ss;
+ std::stringstream& why;
+ std::stringstream& loc;
+ const ExpectationBase* untyped_expectation;
+ bool found;
+ bool is_excessive;
+
+ ~FailureCleanupHandler() {
+ ss << "\n" << why.str();
+
+ if (!found) {
+ // No expectation matches this call - reports a failure.
+ Expect(false, nullptr, -1, ss.str());
+ } else if (is_excessive) {
+ // We had an upper-bound violation and the failure message is in ss.
+ Expect(false, untyped_expectation->file(), untyped_expectation->line(),
+ ss.str());
+ } else {
+ // We had an expected call and the matching expectation is
+ // described in ss.
+ Log(kInfo, loc.str() + ss.str(), 2);
+ }
}
-
- private:
- ActionResultHolder() {}
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
};
template <typename F>
@@ -1465,7 +1446,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
using ArgumentTuple = std::tuple<Args...>;
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
- FunctionMocker() {}
+ FunctionMocker() = default;
// There is no generally useful and implementable semantics of
// copying a mock object, so copying a mock is usually a user error.
@@ -1495,14 +1476,12 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// Returns the ON_CALL spec that matches this mock function with the
// given arguments; returns NULL if no matching ON_CALL is found.
// L = *
- const OnCallSpec<F>* FindOnCallSpec(
- const ArgumentTuple& args) const {
- for (UntypedOnCallSpecs::const_reverse_iterator it
- = untyped_on_call_specs_.rbegin();
+ const OnCallSpec<F>* FindOnCallSpec(const ArgumentTuple& args) const {
+ for (UntypedOnCallSpecs::const_reverse_iterator it =
+ untyped_on_call_specs_.rbegin();
it != untyped_on_call_specs_.rend(); ++it) {
const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it);
- if (spec->Matches(args))
- return spec;
+ if (spec->Matches(args)) return spec;
}
return nullptr;
@@ -1510,15 +1489,14 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// Performs the default action of this mock function on the given
// arguments and returns the result. Asserts (or throws if
- // exceptions are enabled) with a helpful call descrption if there
+ // exceptions are enabled) with a helpful call description if there
// is no valid return value. This method doesn't depend on the
// mutable state of this object, and thus can be called concurrently
// without locking.
// L = *
Result PerformDefaultAction(ArgumentTuple&& args,
const std::string& call_description) const {
- const OnCallSpec<F>* const spec =
- this->FindOnCallSpec(args);
+ const OnCallSpec<F>* const spec = this->FindOnCallSpec(args);
if (spec != nullptr) {
return spec->GetAction().Perform(std::move(args));
}
@@ -1536,32 +1514,6 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
return DefaultValue<Result>::Get();
}
- // Performs the default action with the given arguments and returns
- // the action's result. The call description string will be used in
- // the error message to describe the call in the case the default
- // action fails. The caller is responsible for deleting the result.
- // L = *
- UntypedActionResultHolderBase* UntypedPerformDefaultAction(
- void* untyped_args, // must point to an ArgumentTuple
- const std::string& call_description) const override {
- ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
- return ResultHolder::PerformDefaultAction(this, std::move(*args),
- call_description);
- }
-
- // Performs the given action with the given arguments and returns
- // the action's result. The caller is responsible for deleting the
- // result.
- // L = *
- UntypedActionResultHolderBase* UntypedPerformAction(
- const void* untyped_action, void* untyped_args) const override {
- // Make a copy of the action before performing it, in case the
- // action deletes the mock object (and thus deletes itself).
- const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
- ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
- return ResultHolder::PerformAction(action, std::move(*args));
- }
-
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
// clears the ON_CALL()s set on this mock function.
void ClearDefaultActionsLocked() override
@@ -1579,8 +1531,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
untyped_on_call_specs_.swap(specs_to_delete);
g_gmock_mutex.Unlock();
- for (UntypedOnCallSpecs::const_iterator it =
- specs_to_delete.begin();
+ for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
it != specs_to_delete.end(); ++it) {
delete static_cast<const OnCallSpec<F>*>(*it);
}
@@ -1594,10 +1545,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// arguments. This function can be safely called from multiple
// threads concurrently.
Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
- ArgumentTuple tuple(std::forward<Args>(args)...);
- std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>(
- this->UntypedInvokeWith(static_cast<void*>(&tuple))));
- return holder->Unwrap();
+ return InvokeWith(ArgumentTuple(std::forward<Args>(args)...));
}
MockSpec<F> With(Matcher<Args>... m) {
@@ -1608,13 +1556,10 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
template <typename Function>
friend class MockSpec;
- typedef ActionResultHolder<Result> ResultHolder;
-
// Adds and returns a default action spec for this mock function.
- OnCallSpec<F>& AddNewOnCallSpec(
- const char* file, int line,
- const ArgumentMatcherTuple& m)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ OnCallSpec<F>& AddNewOnCallSpec(const char* file, int line,
+ const ArgumentMatcherTuple& m)
+ GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m);
untyped_on_call_specs_.push_back(on_call_spec);
@@ -1644,7 +1589,8 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
}
private:
- template <typename Func> friend class TypedExpectation;
+ template <typename Func>
+ friend class TypedExpectation;
// Some utilities needed for implementing UntypedInvokeWith().
@@ -1728,9 +1674,8 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// Returns the expectation that matches the arguments, or NULL if no
// expectation matches them.
- TypedExpectation<F>* FindMatchingExpectationLocked(
- const ArgumentTuple& args) const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ TypedExpectation<F>* FindMatchingExpectationLocked(const ArgumentTuple& args)
+ const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
// See the definition of untyped_expectations_ for why access to
// it is unprotected here.
@@ -1747,11 +1692,10 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
}
// Returns a message that the arguments don't match any expectation.
- void FormatUnexpectedCallMessageLocked(
- const ArgumentTuple& args,
- ::std::ostream* os,
- ::std::ostream* why) const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ void FormatUnexpectedCallMessageLocked(const ArgumentTuple& args,
+ ::std::ostream* os,
+ ::std::ostream* why) const
+ GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
*os << "\nUnexpected mock function call - ";
DescribeDefaultActionTo(args, os);
@@ -1760,15 +1704,14 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// Prints a list of expectations that have been tried against the
// current mock function call.
- void PrintTriedExpectationsLocked(
- const ArgumentTuple& args,
- ::std::ostream* why) const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ void PrintTriedExpectationsLocked(const ArgumentTuple& args,
+ ::std::ostream* why) const
+ GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
const size_t count = untyped_expectations_.size();
*why << "Google Mock tried the following " << count << " "
- << (count == 1 ? "expectation, but it didn't match" :
- "expectations, but none matched")
+ << (count == 1 ? "expectation, but it didn't match"
+ : "expectations, but none matched")
<< ":\n";
for (size_t i = 0; i < count; i++) {
TypedExpectation<F>* const expectation =
@@ -1783,11 +1726,176 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
expectation->DescribeCallCountTo(why);
}
}
+
+ // Performs the given action (or the default if it's null) with the given
+ // arguments and returns the action's result.
+ // L = *
+ R PerformAction(const void* untyped_action, ArgumentTuple&& args,
+ const std::string& call_description) const {
+ if (untyped_action == nullptr) {
+ return PerformDefaultAction(std::move(args), call_description);
+ }
+
+ // Make a copy of the action before performing it, in case the
+ // action deletes the mock object (and thus deletes itself).
+ const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
+ return action.Perform(std::move(args));
+ }
+
+ // Is it possible to store an object of the supplied type in a local variable
+ // for the sake of printing it, then return it on to the caller?
+ template <typename T>
+ using can_print_result = internal::conjunction<
+ // void can't be stored as an object (and we also don't need to print it).
+ internal::negation<std::is_void<T>>,
+ // Non-moveable types can't be returned on to the user, so there's no way
+ // for us to intercept and print them.
+ std::is_move_constructible<T>>;
+
+ // Perform the supplied action, printing the result to os.
+ template <typename T = R,
+ typename std::enable_if<can_print_result<T>::value, int>::type = 0>
+ R PerformActionAndPrintResult(const void* const untyped_action,
+ ArgumentTuple&& args,
+ const std::string& call_description,
+ std::ostream& os) {
+ R result = PerformAction(untyped_action, std::move(args), call_description);
+
+ PrintAsActionResult(result, os);
+ return std::forward<R>(result);
+ }
+
+ // An overload for when it's not possible to print the result. In this case we
+ // simply perform the action.
+ template <typename T = R,
+ typename std::enable_if<
+ internal::negation<can_print_result<T>>::value, int>::type = 0>
+ R PerformActionAndPrintResult(const void* const untyped_action,
+ ArgumentTuple&& args,
+ const std::string& call_description,
+ std::ostream&) {
+ return PerformAction(untyped_action, std::move(args), call_description);
+ }
+
+ // Returns the result of invoking this mock function with the given
+ // arguments. This function can be safely called from multiple
+ // threads concurrently.
+ R InvokeWith(ArgumentTuple&& args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
}; // class FunctionMocker
-// Reports an uninteresting call (whose description is in msg) in the
-// manner specified by 'reaction'.
-void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
+// Calculates the result of invoking this mock function with the given
+// arguments, prints it, and returns it.
+template <typename R, typename... Args>
+R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
+ GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ // See the definition of untyped_expectations_ for why access to it
+ // is unprotected here.
+ if (untyped_expectations_.size() == 0) {
+ // No expectation is set on this mock method - we have an
+ // uninteresting call.
+
+ // We must get Google Mock's reaction on uninteresting calls
+ // made on this mock object BEFORE performing the action,
+ // because the action may DELETE the mock object and make the
+ // following expression meaningless.
+ const CallReaction reaction =
+ Mock::GetReactionOnUninterestingCalls(MockObject());
+
+ // True if and only if we need to print this call's arguments and return
+ // value. This definition must be kept in sync with
+ // the behavior of ReportUninterestingCall().
+ const bool need_to_report_uninteresting_call =
+ // If the user allows this uninteresting call, we print it
+ // only when they want informational messages.
+ reaction == kAllow ? LogIsVisible(kInfo) :
+ // If the user wants this to be a warning, we print
+ // it only when they want to see warnings.
+ reaction == kWarn
+ ? LogIsVisible(kWarning)
+ :
+ // Otherwise, the user wants this to be an error, and we
+ // should always print detailed information in the error.
+ true;
+
+ if (!need_to_report_uninteresting_call) {
+ // Perform the action without printing the call information.
+ return this->PerformDefaultAction(
+ std::move(args), "Function call: " + std::string(Name()));
+ }
+
+ // Warns about the uninteresting call.
+ ::std::stringstream ss;
+ this->UntypedDescribeUninterestingCall(&args, &ss);
+
+ // Perform the action, print the result, and then report the uninteresting
+ // call.
+ //
+ // We use RAII to do the latter in case R is void or a non-moveable type. In
+ // either case we can't assign it to a local variable.
+ //
+ // Note that std::bind() is essential here.
+ // We *don't* use any local callback types (like lambdas).
+ // Doing so slows down compilation dramatically because the *constructor* of
+ // std::function<T> is re-instantiated with different template
+ // parameters each time.
+ const UninterestingCallCleanupHandler report_uninteresting_call = {
+ reaction, ss
+ };
+
+ return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);
+ }
+
+ bool is_excessive = false;
+ ::std::stringstream ss;
+ ::std::stringstream why;
+ ::std::stringstream loc;
+ const void* untyped_action = nullptr;
+
+ // The UntypedFindMatchingExpectation() function acquires and
+ // releases g_gmock_mutex.
+
+ const ExpectationBase* const untyped_expectation =
+ this->UntypedFindMatchingExpectation(&args, &untyped_action,
+ &is_excessive, &ss, &why);
+ const bool found = untyped_expectation != nullptr;
+
+ // True if and only if we need to print the call's arguments
+ // and return value.
+ // This definition must be kept in sync with the uses of Expect()
+ // and Log() in this function.
+ const bool need_to_report_call =
+ !found || is_excessive || LogIsVisible(kInfo);
+ if (!need_to_report_call) {
+ // Perform the action without printing the call information.
+ return PerformAction(untyped_action, std::move(args), "");
+ }
+
+ ss << " Function call: " << Name();
+ this->UntypedPrintArgs(&args, &ss);
+
+ // In case the action deletes a piece of the expectation, we
+ // generate the message beforehand.
+ if (found && !is_excessive) {
+ untyped_expectation->DescribeLocationTo(&loc);
+ }
+
+ // Perform the action, print the result, and then fail or log in whatever way
+ // is appropriate.
+ //
+ // We use RAII to do the latter in case R is void or a non-moveable type. In
+ // either case we can't assign it to a local variable.
+ //
+ // Note that we *don't* use any local callback types (like lambdas) here.
+ // Doing so slows down compilation dramatically because the *constructor* of
+ // std::function<T> is re-instantiated with different template
+ // parameters each time.
+ const FailureCleanupHandler handle_failures = {
+ ss, why, loc, untyped_expectation, found, is_excessive
+ };
+
+ return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),
+ ss);
+}
} // namespace internal
@@ -1838,12 +1946,12 @@ corresponding to the provided F argument.
It makes use of MockFunction easier by allowing it to accept more F arguments
than just function signatures.
-Specializations provided here cover only a signature type itself and
-std::function. However, if need be it can be easily extended to cover also other
-types (like for example boost::function).
+Specializations provided here cover a signature type itself and any template
+that can be parameterized with a signature, including std::function and
+boost::function.
*/
-template <typename F>
+template <typename F, typename = void>
struct SignatureOf;
template <typename R, typename... Args>
@@ -1851,8 +1959,10 @@ struct SignatureOf<R(Args...)> {
using type = R(Args...);
};
-template <typename F>
-struct SignatureOf<std::function<F>> : SignatureOf<F> {};
+template <template <typename> class C, typename F>
+struct SignatureOf<C<F>,
+ typename std::enable_if<std::is_function<F>::value>::type>
+ : SignatureOf<F> {};
template <typename F>
using SignatureOfT = typename SignatureOf<F>::type;
@@ -1950,7 +2060,9 @@ using internal::MockSpec;
// // Expects a call to const MockFoo::Bar().
// EXPECT_CALL(Const(foo), Bar());
template <typename T>
-inline const T& Const(const T& x) { return x; }
+inline const T& Const(const T& x) {
+ return x;
+}
// Constructs an Expectation object that references and co-owns exp.
inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT