gmock-spec-builders.h (googletest-release-1.11.0) | : | gmock-spec-builders.h (googletest-release-1.12.0) | ||
---|---|---|---|---|
skipping to change at line 58 | skipping to change at line 58 | |||
// .Times(cardinality) | // .Times(cardinality) | |||
// .InSequence(sequences) | // .InSequence(sequences) | |||
// .After(expectations) | // .After(expectations) | |||
// .WillOnce(action) | // .WillOnce(action) | |||
// .WillRepeatedly(action) | // .WillRepeatedly(action) | |||
// .RetiresOnSaturation(); | // .RetiresOnSaturation(); | |||
// | // | |||
// where all clauses are optional, and .InSequence()/.After()/ | // where all clauses are optional, and .InSequence()/.After()/ | |||
// .WillOnce() can appear any number of times. | // .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_ | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ | |||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ | |||
#include <cstdint> | ||||
#include <functional> | #include <functional> | |||
#include <map> | #include <map> | |||
#include <memory> | #include <memory> | |||
#include <set> | #include <set> | |||
#include <sstream> | #include <sstream> | |||
#include <string> | #include <string> | |||
#include <type_traits> | #include <type_traits> | |||
#include <utility> | #include <utility> | |||
#include <vector> | #include <vector> | |||
#include "gmock/gmock-actions.h" | #include "gmock/gmock-actions.h" | |||
#include "gmock/gmock-cardinalities.h" | #include "gmock/gmock-cardinalities.h" | |||
#include "gmock/gmock-matchers.h" | #include "gmock/gmock-matchers.h" | |||
#include "gmock/internal/gmock-internal-utils.h" | #include "gmock/internal/gmock-internal-utils.h" | |||
#include "gmock/internal/gmock-port.h" | #include "gmock/internal/gmock-port.h" | |||
#include "gtest/gtest.h" | #include "gtest/gtest.h" | |||
#if GTEST_HAS_EXCEPTIONS | #if GTEST_HAS_EXCEPTIONS | |||
# include <stdexcept> // NOLINT | #include <stdexcept> // NOLINT | |||
#endif | #endif | |||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ | |||
/* class A needs to have dll-interface to be used by clients of class B */) | /* class A needs to have dll-interface to be used by clients of class B */) | |||
namespace testing { | namespace testing { | |||
// An abstract handle of an expectation. | // An abstract handle of an expectation. | |||
class Expectation; | class Expectation; | |||
// A set of expectation handles. | // A set of expectation handles. | |||
class ExpectationSet; | class ExpectationSet; | |||
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION | // Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION | |||
// and MUST NOT BE USED IN USER CODE!!! | // and MUST NOT BE USED IN USER CODE!!! | |||
namespace internal { | namespace internal { | |||
// Implements a mock function. | // Implements a mock function. | |||
template <typename F> class FunctionMocker; | template <typename F> | |||
class FunctionMocker; | ||||
// Base class for expectations. | // Base class for expectations. | |||
class ExpectationBase; | class ExpectationBase; | |||
// Implements an expectation. | // Implements an expectation. | |||
template <typename F> class TypedExpectation; | template <typename F> | |||
class TypedExpectation; | ||||
// Helper class for testing the Expectation class template. | // Helper class for testing the Expectation class template. | |||
class ExpectationTester; | class ExpectationTester; | |||
// Helper classes for implementing NiceMock, StrictMock, and NaggyMock. | // Helper classes for implementing NiceMock, StrictMock, and NaggyMock. | |||
template <typename MockClass> | template <typename MockClass> | |||
class NiceMockImpl; | class NiceMockImpl; | |||
template <typename MockClass> | template <typename MockClass> | |||
class StrictMockImpl; | class StrictMockImpl; | |||
template <typename MockClass> | template <typename MockClass> | |||
skipping to change at line 131 | skipping to change at line 136 | |||
// The reason we don't use more fine-grained protection is: when a | // The reason we don't use more fine-grained protection is: when a | |||
// mock function Foo() is called, it needs to consult its expectations | // mock function Foo() is called, it needs to consult its expectations | |||
// to see which one should be picked. If another thread is allowed to | // to see which one should be picked. If another thread is allowed to | |||
// call a mock function (either Foo() or a different one) at the same | // call a mock function (either Foo() or a different one) at the same | |||
// time, it could affect the "retired" attributes of Foo()'s | // time, it could affect the "retired" attributes of Foo()'s | |||
// expectations when InSequence() is used, and thus affect which | // expectations when InSequence() is used, and thus affect which | |||
// expectation gets picked. Therefore, we sequence all mock function | // expectation gets picked. Therefore, we sequence all mock function | |||
// calls to ensure the integrity of the mock objects' states. | // calls to ensure the integrity of the mock objects' states. | |||
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex); | 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 | // Abstract base class of FunctionMocker. This is the | |||
// type-agnostic part of the function mocker interface. Its pure | // type-agnostic part of the function mocker interface. Its pure | |||
// virtual methods are implemented by FunctionMocker. | // virtual methods are implemented by FunctionMocker. | |||
class GTEST_API_ UntypedFunctionMockerBase { | class GTEST_API_ UntypedFunctionMockerBase { | |||
public: | public: | |||
UntypedFunctionMockerBase(); | UntypedFunctionMockerBase(); | |||
virtual ~UntypedFunctionMockerBase(); | virtual ~UntypedFunctionMockerBase(); | |||
// Verifies that all expectations on this mock function have been | // Verifies that all expectations on this mock function have been | |||
// satisfied. Reports one or more Google Test non-fatal failures | // satisfied. Reports one or more Google Test non-fatal failures | |||
skipping to change at line 156 | skipping to change at line 158 | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); | |||
// Clears the ON_CALL()s set on this mock function. | // Clears the ON_CALL()s set on this mock function. | |||
virtual void ClearDefaultActionsLocked() | virtual void ClearDefaultActionsLocked() | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0; | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0; | |||
// In all of the following Untyped* functions, it's the caller's | // In all of the following Untyped* functions, it's the caller's | |||
// responsibility to guarantee the correctness of the arguments' | // responsibility to guarantee the correctness of the arguments' | |||
// types. | // 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 | // 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 | |||
// ostream. | // ostream. | |||
virtual void UntypedDescribeUninterestingCall( | virtual void UntypedDescribeUninterestingCall(const void* untyped_args, | |||
const void* untyped_args, | ::std::ostream* os) const | |||
::std::ostream* os) const | GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0; | |||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0; | ||||
// Returns the expectation that matches the given function arguments | // Returns the expectation that matches the given function arguments | |||
// (or NULL is there's no match); when a match is found, | // (or NULL is there's no match); when a match is found, | |||
// untyped_action is set to point to the action that should be | // untyped_action is set to point to the action that should be | |||
// performed (or NULL if the action is "do default"), and | // performed (or NULL if the action is "do default"), and | |||
// is_excessive is modified to indicate whether the call exceeds the | // is_excessive is modified to indicate whether the call exceeds the | |||
// expected number. | // expected number. | |||
virtual const ExpectationBase* UntypedFindMatchingExpectation( | virtual const ExpectationBase* UntypedFindMatchingExpectation( | |||
const void* untyped_args, | const void* untyped_args, const void** untyped_action, bool* is_excessive, | |||
const void** untyped_action, bool* is_excessive, | ||||
::std::ostream* what, ::std::ostream* why) | ::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. | // Prints the given function arguments to the ostream. | |||
virtual void UntypedPrintArgs(const void* untyped_args, | virtual void UntypedPrintArgs(const void* untyped_args, | |||
::std::ostream* os) const = 0; | ::std::ostream* os) const = 0; | |||
// Sets the mock object this mock method belongs to, and registers | // Sets the mock object this mock method belongs to, and registers | |||
// this information in the global mock registry. Will be called | // this information in the global mock registry. Will be called | |||
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock | // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock | |||
// method. | // method. | |||
void RegisterOwner(const void* mock_obj) | void RegisterOwner(const void* mock_obj) GTEST_LOCK_EXCLUDED_(g_gmock_mutex); | |||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); | ||||
// Sets the mock object this mock method belongs to, and sets the | // Sets the mock object this mock method belongs to, and sets the | |||
// name of the mock function. Will be called upon each invocation | // name of the mock function. Will be called upon each invocation | |||
// of this mock function. | // of this mock function. | |||
void SetOwnerAndName(const void* mock_obj, const char* name) | void SetOwnerAndName(const void* mock_obj, const char* name) | |||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); | GTEST_LOCK_EXCLUDED_(g_gmock_mutex); | |||
// Returns the mock object this mock method belongs to. Must be | // Returns the mock object this mock method belongs to. Must be | |||
// called after RegisterOwner() or SetOwnerAndName() has been | // called after RegisterOwner() or SetOwnerAndName() has been | |||
// called. | // called. | |||
const void* MockObject() const | const void* MockObject() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex); | |||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); | ||||
// Returns the name of this mock method. Must be called after | // Returns the name of this mock method. Must be called after | |||
// SetOwnerAndName() has been called. | // SetOwnerAndName() has been called. | |||
const char* Name() const | const char* Name() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex); | |||
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); | ||||
protected: | protected: | |||
typedef std::vector<const void*> UntypedOnCallSpecs; | typedef std::vector<const void*> UntypedOnCallSpecs; | |||
using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>; | using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>; | |||
// Returns an Expectation object that references and co-owns exp, | // Returns an Expectation object that references and co-owns exp, | |||
// which must be an expectation on this mock function. | // which must be an expectation on this mock function. | |||
Expectation GetHandleOf(ExpectationBase* exp); | Expectation GetHandleOf(ExpectationBase* exp); | |||
skipping to change at line 432 | skipping to change at line 408 | |||
template <typename MockClass> | template <typename MockClass> | |||
friend class internal::NiceMockImpl; | friend class internal::NiceMockImpl; | |||
template <typename MockClass> | template <typename MockClass> | |||
friend class internal::NaggyMockImpl; | friend class internal::NaggyMockImpl; | |||
template <typename MockClass> | template <typename MockClass> | |||
friend class internal::StrictMockImpl; | friend class internal::StrictMockImpl; | |||
// Tells Google Mock to allow uninteresting calls on the given mock | // Tells Google Mock to allow uninteresting calls on the given mock | |||
// object. | // object. | |||
static void AllowUninterestingCalls(const void* mock_obj) | static void AllowUninterestingCalls(uintptr_t mock_obj) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | |||
// Tells Google Mock to warn the user about uninteresting calls on | // Tells Google Mock to warn the user about uninteresting calls on | |||
// the given mock object. | // 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); | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | |||
// Tells Google Mock to fail uninteresting calls on the given mock | // Tells Google Mock to fail uninteresting calls on the given mock | |||
// object. | // object. | |||
static void FailUninterestingCalls(const void* mock_obj) | static void FailUninterestingCalls(uintptr_t mock_obj) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | |||
// Tells Google Mock the given mock object is being destroyed and | // Tells Google Mock the given mock object is being destroyed and | |||
// its entry in the call-reaction table should be removed. | // 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); | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | |||
// Returns the reaction Google Mock will have on uninteresting calls | // Returns the reaction Google Mock will have on uninteresting calls | |||
// made on the given mock object. | // made on the given mock object. | |||
static internal::CallReaction GetReactionOnUninterestingCalls( | static internal::CallReaction GetReactionOnUninterestingCalls( | |||
const void* mock_obj) | const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | ||||
// Verifies that all expectations on the given mock object have been | // Verifies that all expectations on the given mock object have been | |||
// satisfied. Reports one or more Google Test non-fatal failures | // satisfied. Reports one or more Google Test non-fatal failures | |||
// and returns false if not. | // and returns false if not. | |||
static bool VerifyAndClearExpectationsLocked(void* mock_obj) | static bool VerifyAndClearExpectationsLocked(void* mock_obj) | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); | GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); | |||
// Clears all ON_CALL()s set on the given mock object. | // Clears all ON_CALL()s set on the given mock object. | |||
static void ClearDefaultActionsLocked(void* mock_obj) | static void ClearDefaultActionsLocked(void* mock_obj) | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); | GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); | |||
// Registers a mock object and a mock method it owns. | // Registers a mock object and a mock method it owns. | |||
static void Register( | static void Register(const void* mock_obj, | |||
const void* mock_obj, | internal::UntypedFunctionMockerBase* mocker) | |||
internal::UntypedFunctionMockerBase* mocker) | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | ||||
// Tells Google Mock where in the source code mock_obj is used in an | // 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 | // ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this | |||
// information helps the user identify which object it is. | // information helps the user identify which object it is. | |||
static void RegisterUseByOnCallOrExpectCall( | static void RegisterUseByOnCallOrExpectCall(const void* mock_obj, | |||
const void* mock_obj, const char* file, int line) | const char* file, int line) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); | |||
// Unregisters a mock method; removes the owning mock object from | // Unregisters a mock method; removes the owning mock object from | |||
// the registry when the last mock method associated with it has | // the registry when the last mock method associated with it has | |||
// been unregistered. This is called only in the destructor of | // been unregistered. This is called only in the destructor of | |||
// FunctionMocker. | // FunctionMocker. | |||
static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) | static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); | GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); | |||
}; // class Mock | }; // class Mock | |||
// An abstract handle of an expectation. Useful in the .After() | // An abstract handle of an expectation. Useful in the .After() | |||
skipping to change at line 679 | skipping to change at line 653 | |||
// You can create InSequence objects in multiple threads, as long as | // You can create InSequence objects in multiple threads, as long as | |||
// they are used to affect different mock objects. The idea is that | // they are used to affect different mock objects. The idea is that | |||
// each thread can create and set up its own mocks as if it's the only | // each thread can create and set up its own mocks as if it's the only | |||
// thread. However, for clarity of your tests we recommend you to set | // thread. However, for clarity of your tests we recommend you to set | |||
// up mocks in the main thread unless you have a good reason not to do | // up mocks in the main thread unless you have a good reason not to do | |||
// so. | // so. | |||
class GTEST_API_ InSequence { | class GTEST_API_ InSequence { | |||
public: | public: | |||
InSequence(); | InSequence(); | |||
~InSequence(); | ~InSequence(); | |||
private: | private: | |||
bool sequence_created_; | bool sequence_created_; | |||
GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence); // NOLINT | InSequence(const InSequence&) = delete; | |||
InSequence& operator=(const InSequence&) = delete; | ||||
} GTEST_ATTRIBUTE_UNUSED_; | } GTEST_ATTRIBUTE_UNUSED_; | |||
namespace internal { | namespace internal { | |||
// Points to the implicit sequence introduced by a living InSequence | // Points to the implicit sequence introduced by a living InSequence | |||
// object (if any) in the current thread or NULL. | // object (if any) in the current thread or NULL. | |||
GTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence; | GTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence; | |||
// Base class for implementing expectations. | // Base class for implementing expectations. | |||
// | // | |||
skipping to change at line 785 | skipping to change at line 761 | |||
// Sets the cardinality of this expectation spec. | // Sets the cardinality of this expectation spec. | |||
void set_cardinality(const Cardinality& a_cardinality) { | void set_cardinality(const Cardinality& a_cardinality) { | |||
cardinality_ = a_cardinality; | cardinality_ = a_cardinality; | |||
} | } | |||
// The following group of methods should only be called after the | // The following group of methods should only be called after the | |||
// EXPECT_CALL() statement, and only when g_gmock_mutex is held by | // EXPECT_CALL() statement, and only when g_gmock_mutex is held by | |||
// the current thread. | // the current thread. | |||
// Retires all pre-requisites of this expectation. | // Retires all pre-requisites of this expectation. | |||
void RetireAllPreRequisites() | void RetireAllPreRequisites() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); | ||||
// Returns true if and only if this expectation is retired. | // Returns true if and only if this expectation is retired. | |||
bool is_retired() const | bool is_retired() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
return retired_; | return retired_; | |||
} | } | |||
// Retires this expectation. | // Retires this expectation. | |||
void Retire() | void Retire() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
retired_ = true; | retired_ = true; | |||
} | } | |||
// Returns true if and only if this expectation is satisfied. | // Returns true if and only if this expectation is satisfied. | |||
bool IsSatisfied() const | bool IsSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
return cardinality().IsSatisfiedByCallCount(call_count_); | return cardinality().IsSatisfiedByCallCount(call_count_); | |||
} | } | |||
// Returns true if and only if this expectation is saturated. | // Returns true if and only if this expectation is saturated. | |||
bool IsSaturated() const | bool IsSaturated() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
return cardinality().IsSaturatedByCallCount(call_count_); | return cardinality().IsSaturatedByCallCount(call_count_); | |||
} | } | |||
// Returns true if and only if this expectation is over-saturated. | // Returns true if and only if this expectation is over-saturated. | |||
bool IsOverSaturated() const | bool IsOverSaturated() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
return cardinality().IsOverSaturatedByCallCount(call_count_); | return cardinality().IsOverSaturatedByCallCount(call_count_); | |||
} | } | |||
// Returns true if and only if all pre-requisites of this expectation are | // Returns true if and only if all pre-requisites of this expectation are | |||
// satisfied. | // satisfied. | |||
bool AllPrerequisitesAreSatisfied() const | bool AllPrerequisitesAreSatisfied() const | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); | |||
// Adds unsatisfied pre-requisites of this expectation to 'result'. | // Adds unsatisfied pre-requisites of this expectation to 'result'. | |||
void FindUnsatisfiedPrerequisites(ExpectationSet* result) const | void FindUnsatisfiedPrerequisites(ExpectationSet* result) const | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); | |||
// Returns the number this expectation has been invoked. | // Returns the number this expectation has been invoked. | |||
int call_count() const | int call_count() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
return call_count_; | return call_count_; | |||
} | } | |||
// Increments the number this expectation has been invoked. | // Increments the number this expectation has been invoked. | |||
void IncrementCallCount() | void IncrementCallCount() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
call_count_++; | call_count_++; | |||
} | } | |||
// Checks the action count (i.e. the number of WillOnce() and | // Checks the action count (i.e. the number of WillOnce() and | |||
// WillRepeatedly() clauses) against the cardinality if this hasn't | // WillRepeatedly() clauses) against the cardinality if this hasn't | |||
// been done before. Prints a warning if there are too many or too | // been done before. Prints a warning if there are too many or too | |||
// few actions. | // few actions. | |||
void CheckActionCountIfNotDone() const | void CheckActionCountIfNotDone() const GTEST_LOCK_EXCLUDED_(mutex_); | |||
GTEST_LOCK_EXCLUDED_(mutex_); | ||||
friend class ::testing::Sequence; | friend class ::testing::Sequence; | |||
friend class ::testing::internal::ExpectationTester; | friend class ::testing::internal::ExpectationTester; | |||
template <typename Function> | template <typename Function> | |||
friend class TypedExpectation; | friend class TypedExpectation; | |||
// Implements the .Times() clause. | // Implements the .Times() clause. | |||
void UntypedTimes(const Cardinality& a_cardinality); | void UntypedTimes(const Cardinality& a_cardinality); | |||
// This group of fields are part of the spec and won't change after | // This group of fields are part of the spec and won't change after | |||
// an EXPECT_CALL() statement finishes. | // an EXPECT_CALL() statement finishes. | |||
const char* file_; // The file that contains the expectation. | const char* file_; // The file that contains the expectation. | |||
int line_; // The line number of the expectation. | int line_; // The line number of the expectation. | |||
const std::string source_text_; // The EXPECT_CALL(...) source text. | const std::string source_text_; // The EXPECT_CALL(...) source text. | |||
// True if and only if the cardinality is specified explicitly. | // True if and only if the cardinality is specified explicitly. | |||
bool cardinality_specified_; | 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 | // The immediate pre-requisites (i.e. expectations that must be | |||
// satisfied before this expectation can be matched) of this | // satisfied before this expectation can be matched) of this | |||
// expectation. We use std::shared_ptr in the set because we want an | // expectation. We use std::shared_ptr in the set because we want an | |||
// Expectation object to be co-owned by its FunctionMocker and its | // Expectation object to be co-owned by its FunctionMocker and its | |||
// successors. This allows multiple mock objects to be deleted at | // successors. This allows multiple mock objects to be deleted at | |||
// different times. | // different times. | |||
ExpectationSet immediate_prerequisites_; | ExpectationSet immediate_prerequisites_; | |||
// This group of fields are the current state of the expectation, | // This group of fields are the current state of the expectation, | |||
// and can change as the mock function is called. | // and can change as the mock function is called. | |||
int call_count_; // How many times this expectation has been invoked. | int call_count_; // How many times this expectation has been invoked. | |||
bool retired_; // True if and only if this expectation has retired. | bool retired_; // True if and only if this expectation has retired. | |||
UntypedActions untyped_actions_; | UntypedActions untyped_actions_; | |||
bool extra_matcher_specified_; | bool extra_matcher_specified_; | |||
bool repeated_action_specified_; // True if a WillRepeatedly() was specified. | bool repeated_action_specified_; // True if a WillRepeatedly() was specified. | |||
bool retires_on_saturation_; | bool retires_on_saturation_; | |||
Clause last_clause_; | Clause last_clause_; | |||
mutable bool action_count_checked_; // Under mutex_. | mutable bool action_count_checked_; // Under mutex_. | |||
mutable Mutex mutex_; // Protects action_count_checked_. | mutable Mutex mutex_; // Protects action_count_checked_. | |||
}; // class ExpectationBase | }; // class ExpectationBase | |||
// Impements an expectation for the given function type. | ||||
template <typename F> | 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: | public: | |||
typedef typename Function<F>::ArgumentTuple ArgumentTuple; | typedef typename Function<F>::ArgumentTuple ArgumentTuple; | |||
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; | typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; | |||
typedef typename Function<F>::Result Result; | typedef typename Function<F>::Result Result; | |||
TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line, | TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line, | |||
const std::string& a_source_text, | const std::string& a_source_text, | |||
const ArgumentMatcherTuple& m) | const ArgumentMatcherTuple& m) | |||
: ExpectationBase(a_file, a_line, a_source_text), | : ExpectationBase(a_file, a_line, a_source_text), | |||
owner_(owner), | owner_(owner), | |||
skipping to change at line 946 | skipping to change at line 919 | |||
return *this; | return *this; | |||
} | } | |||
// Implements the .Times() clause. | // Implements the .Times() clause. | |||
TypedExpectation& Times(const Cardinality& a_cardinality) { | TypedExpectation& Times(const Cardinality& a_cardinality) { | |||
ExpectationBase::UntypedTimes(a_cardinality); | ExpectationBase::UntypedTimes(a_cardinality); | |||
return *this; | return *this; | |||
} | } | |||
// Implements the .Times() clause. | // Implements the .Times() clause. | |||
TypedExpectation& Times(int n) { | TypedExpectation& Times(int n) { return Times(Exactly(n)); } | |||
return Times(Exactly(n)); | ||||
} | ||||
// Implements the .InSequence() clause. | // Implements the .InSequence() clause. | |||
TypedExpectation& InSequence(const Sequence& s) { | TypedExpectation& InSequence(const Sequence& s) { | |||
ExpectSpecProperty(last_clause_ <= kInSequence, | ExpectSpecProperty(last_clause_ <= kInSequence, | |||
".InSequence() cannot appear after .After()," | ".InSequence() cannot appear after .After()," | |||
" .WillOnce(), .WillRepeatedly(), or " | " .WillOnce(), .WillRepeatedly(), or " | |||
".RetiresOnSaturation()."); | ".RetiresOnSaturation()."); | |||
last_clause_ = kInSequence; | last_clause_ = kInSequence; | |||
s.AddExpectation(GetHandle()); | s.AddExpectation(GetHandle()); | |||
skipping to change at line 1008 | skipping to change at line 979 | |||
TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, | TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, | |||
const ExpectationSet& s3, const ExpectationSet& s4) { | const ExpectationSet& s3, const ExpectationSet& s4) { | |||
return After(s1, s2, s3).After(s4); | return After(s1, s2, s3).After(s4); | |||
} | } | |||
TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, | TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, | |||
const ExpectationSet& s3, const ExpectationSet& s4, | const ExpectationSet& s3, const ExpectationSet& s4, | |||
const ExpectationSet& s5) { | const ExpectationSet& s5) { | |||
return After(s1, s2, s3, s4).After(s5); | return After(s1, s2, s3, s4).After(s5); | |||
} | } | |||
// Implements the .WillOnce() clause. | // Preferred, type-safe overload: consume anything that can be directly | |||
TypedExpectation& WillOnce(const Action<F>& action) { | // 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, | ExpectSpecProperty(last_clause_ <= kWillOnce, | |||
".WillOnce() cannot appear after " | ".WillOnce() cannot appear after " | |||
".WillRepeatedly() or .RetiresOnSaturation()."); | ".WillRepeatedly() or .RetiresOnSaturation()."); | |||
last_clause_ = kWillOnce; | last_clause_ = kWillOnce; | |||
untyped_actions_.push_back(new Action<F>(action)); | untyped_actions_.push_back(new Action<F>(std::move(action))); | |||
if (!cardinality_specified()) { | if (!cardinality_specified()) { | |||
set_cardinality(Exactly(static_cast<int>(untyped_actions_.size()))); | set_cardinality(Exactly(static_cast<int>(untyped_actions_.size()))); | |||
} | } | |||
return *this; | return *this; | |||
} | } | |||
// Implements the .WillRepeatedly() clause. | // Implements the .WillRepeatedly() clause. | |||
TypedExpectation& WillRepeatedly(const Action<F>& action) { | TypedExpectation& WillRepeatedly(const Action<F>& action) { | |||
if (last_clause_ == kWillRepeatedly) { | if (last_clause_ == kWillRepeatedly) { | |||
ExpectSpecProperty(false, | ExpectSpecProperty(false, | |||
skipping to change at line 1063 | skipping to change at line 1051 | |||
retires_on_saturation_ = true; | retires_on_saturation_ = true; | |||
// Now that no more action clauses can be specified, we check | // Now that no more action clauses can be specified, we check | |||
// whether their count makes sense. | // whether their count makes sense. | |||
CheckActionCountIfNotDone(); | CheckActionCountIfNotDone(); | |||
return *this; | return *this; | |||
} | } | |||
// Returns the matchers for the arguments as specified inside the | // Returns the matchers for the arguments as specified inside the | |||
// EXPECT_CALL() macro. | // EXPECT_CALL() macro. | |||
const ArgumentMatcherTuple& matchers() const { | const ArgumentMatcherTuple& matchers() const { return matchers_; } | |||
return matchers_; | ||||
} | ||||
// Returns the matcher specified by the .With() clause. | // Returns the matcher specified by the .With() clause. | |||
const Matcher<const ArgumentTuple&>& extra_matcher() const { | const Matcher<const ArgumentTuple&>& extra_matcher() const { | |||
return extra_matcher_; | return extra_matcher_; | |||
} | } | |||
// Returns the action specified by the .WillRepeatedly() clause. | // Returns the action specified by the .WillRepeatedly() clause. | |||
const Action<F>& repeated_action() const { return repeated_action_; } | const Action<F>& repeated_action() const { return repeated_action_; } | |||
// If this mock method has an extra matcher (i.e. .With(matcher)), | // If this mock method has an extra matcher (i.e. .With(matcher)), | |||
skipping to change at line 1089 | skipping to change at line 1075 | |||
*os << " Expected args: "; | *os << " Expected args: "; | |||
extra_matcher_.DescribeTo(os); | extra_matcher_.DescribeTo(os); | |||
*os << "\n"; | *os << "\n"; | |||
} | } | |||
} | } | |||
private: | private: | |||
template <typename Function> | template <typename Function> | |||
friend class FunctionMocker; | 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 | // Returns an Expectation object that references and co-owns this | |||
// expectation. | // expectation. | |||
Expectation GetHandle() override { return owner_->GetHandleOf(this); } | Expectation GetHandle() override { return owner_->GetHandleOf(this); } | |||
// The following methods will be called only after the EXPECT_CALL() | // The following methods will be called only after the EXPECT_CALL() | |||
// statement finishes and when the current thread holds | // statement finishes and when the current thread holds | |||
// g_gmock_mutex. | // g_gmock_mutex. | |||
// Returns true if and only if this expectation matches the given arguments. | // Returns true if and only if this expectation matches the given arguments. | |||
bool Matches(const ArgumentTuple& args) const | bool Matches(const ArgumentTuple& args) const | |||
skipping to change at line 1120 | skipping to change at line 1116 | |||
// In case the action count wasn't checked when the expectation | // In case the action count wasn't checked when the expectation | |||
// was defined (e.g. if this expectation has no WillRepeatedly() | // was defined (e.g. if this expectation has no WillRepeatedly() | |||
// or RetiresOnSaturation() clause), we check it when the | // or RetiresOnSaturation() clause), we check it when the | |||
// expectation is used for the first time. | // expectation is used for the first time. | |||
CheckActionCountIfNotDone(); | CheckActionCountIfNotDone(); | |||
return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args); | return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args); | |||
} | } | |||
// Describes the result of matching the arguments against this | // Describes the result of matching the arguments against this | |||
// expectation to the given ostream. | // expectation to the given ostream. | |||
void ExplainMatchResultTo( | void ExplainMatchResultTo(const ArgumentTuple& args, ::std::ostream* os) const | |||
const ArgumentTuple& args, | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
::std::ostream* os) const | ||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
if (is_retired()) { | if (is_retired()) { | |||
*os << " Expected: the expectation is active\n" | *os << " Expected: the expectation is active\n" | |||
<< " Actual: it is retired\n"; | << " Actual: it is retired\n"; | |||
} else if (!Matches(args)) { | } else if (!Matches(args)) { | |||
if (!TupleMatches(matchers_, args)) { | if (!TupleMatches(matchers_, args)) { | |||
ExplainMatchFailureTupleTo(matchers_, args, os); | ExplainMatchFailureTupleTo(matchers_, args, os); | |||
} | } | |||
StringMatchResultListener listener; | StringMatchResultListener listener; | |||
skipping to change at line 1182 | skipping to change at line 1176 | |||
"called - this should never happen."); | "called - this should never happen."); | |||
const int action_count = static_cast<int>(untyped_actions_.size()); | const int action_count = static_cast<int>(untyped_actions_.size()); | |||
if (action_count > 0 && !repeated_action_specified_ && | if (action_count > 0 && !repeated_action_specified_ && | |||
count > action_count) { | count > action_count) { | |||
// If there is at least one WillOnce() and no WillRepeatedly(), | // If there is at least one WillOnce() and no WillRepeatedly(), | |||
// we warn the user when the WillOnce() clauses ran out. | // we warn the user when the WillOnce() clauses ran out. | |||
::std::stringstream ss; | ::std::stringstream ss; | |||
DescribeLocationTo(&ss); | DescribeLocationTo(&ss); | |||
ss << "Actions ran out in " << source_text() << "...\n" | ss << "Actions ran out in " << source_text() << "...\n" | |||
<< "Called " << count << " times, but only " | << "Called " << count << " times, but only " << action_count | |||
<< action_count << " WillOnce()" | << " WillOnce()" << (action_count == 1 ? " is" : "s are") | |||
<< (action_count == 1 ? " is" : "s are") << " specified - "; | << " specified - "; | |||
mocker->DescribeDefaultActionTo(args, &ss); | mocker->DescribeDefaultActionTo(args, &ss); | |||
Log(kWarning, ss.str(), 1); | Log(kWarning, ss.str(), 1); | |||
} | } | |||
return count <= action_count | return count <= action_count | |||
? *static_cast<const Action<F>*>( | ? *static_cast<const Action<F>*>( | |||
untyped_actions_[static_cast<size_t>(count - 1)]) | untyped_actions_[static_cast<size_t>(count - 1)]) | |||
: repeated_action(); | : repeated_action(); | |||
} | } | |||
skipping to change at line 1226 | skipping to change at line 1220 | |||
} | } | |||
IncrementCallCount(); | IncrementCallCount(); | |||
RetireAllPreRequisites(); | RetireAllPreRequisites(); | |||
if (retires_on_saturation_ && IsSaturated()) { | if (retires_on_saturation_ && IsSaturated()) { | |||
Retire(); | Retire(); | |||
} | } | |||
// Must be done after IncrementCount()! | // Must be done after IncrementCount()! | |||
*what << "Mock function call matches " << source_text() <<"...\n"; | *what << "Mock function call matches " << source_text() << "...\n"; | |||
return &(GetCurrentAction(mocker, args)); | return &(GetCurrentAction(mocker, args)); | |||
} | } | |||
// All the fields below won't change once the EXPECT_CALL() | // All the fields below won't change once the EXPECT_CALL() | |||
// statement finishes. | // statement finishes. | |||
FunctionMocker<F>* const owner_; | FunctionMocker<F>* const owner_; | |||
ArgumentMatcherTuple matchers_; | ArgumentMatcherTuple matchers_; | |||
Matcher<const ArgumentTuple&> extra_matcher_; | Matcher<const ArgumentTuple&> extra_matcher_; | |||
Action<F> repeated_action_; | Action<F> repeated_action_; | |||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TypedExpectation); | TypedExpectation(const TypedExpectation&) = delete; | |||
TypedExpectation& operator=(const TypedExpectation&) = delete; | ||||
}; // class TypedExpectation | }; // class TypedExpectation | |||
// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for | // A MockSpec object is used by ON_CALL() or EXPECT_CALL() for | |||
// specifying the default behavior of, or expectation on, a mock | // specifying the default behavior of, or expectation on, a mock | |||
// function. | // function. | |||
// Note: class MockSpec really belongs to the ::testing namespace. | // Note: class MockSpec really belongs to the ::testing namespace. | |||
// However if we define it in ::testing, MSVC will complain when | // However if we define it in ::testing, MSVC will complain when | |||
// classes in ::testing::internal declare it as a friend class | // classes in ::testing::internal declare it as a friend class | |||
// template. To workaround this compiler bug, we define MockSpec in | // template. To workaround this compiler bug, we define MockSpec in | |||
skipping to change at line 1259 | skipping to change at line 1254 | |||
// Logs a message including file and line number information. | // Logs a message including file and line number information. | |||
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, | GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, | |||
const char* file, int line, | const char* file, int line, | |||
const std::string& message); | const std::string& message); | |||
template <typename F> | template <typename F> | |||
class MockSpec { | class MockSpec { | |||
public: | public: | |||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; | typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; | |||
typedef typename internal::Function<F>::ArgumentMatcherTuple | typedef | |||
ArgumentMatcherTuple; | typename internal::Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; | |||
// 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. | |||
MockSpec(internal::FunctionMocker<F>* function_mocker, | MockSpec(internal::FunctionMocker<F>* function_mocker, | |||
const ArgumentMatcherTuple& matchers) | const ArgumentMatcherTuple& matchers) | |||
: function_mocker_(function_mocker), matchers_(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. | |||
internal::OnCallSpec<F>& InternalDefaultActionSetAt( | internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file, | |||
const char* file, int line, const char* obj, const char* call) { | int line, const char* obj, | |||
const char* call) { | ||||
LogWithLocation(internal::kInfo, file, line, | LogWithLocation(internal::kInfo, file, line, | |||
std::string("ON_CALL(") + obj + ", " + call + ") invoked"); | std::string("ON_CALL(") + obj + ", " + call + ") invoked"); | |||
return function_mocker_->AddNewOnCallSpec(file, line, matchers_); | return function_mocker_->AddNewOnCallSpec(file, line, matchers_); | |||
} | } | |||
// Adds a new expectation spec to the function mocker and returns | // Adds a new expectation spec to the function mocker and returns | |||
// the newly created spec. | // the newly created spec. | |||
internal::TypedExpectation<F>& InternalExpectedAt( | internal::TypedExpectation<F>& InternalExpectedAt(const char* file, int line, | |||
const char* file, int line, const char* obj, const char* call) { | const char* obj, | |||
const char* call) { | ||||
const std::string source_text(std::string("EXPECT_CALL(") + obj + ", " + | const std::string source_text(std::string("EXPECT_CALL(") + obj + ", " + | |||
call + ")"); | call + ")"); | |||
LogWithLocation(internal::kInfo, file, line, source_text + " invoked"); | LogWithLocation(internal::kInfo, file, line, source_text + " invoked"); | |||
return function_mocker_->AddNewExpectation( | return function_mocker_->AddNewExpectation(file, line, source_text, | |||
file, line, source_text, matchers_); | matchers_); | |||
} | } | |||
// This operator overload is used to swallow the superfluous parameter list | // This operator overload is used to swallow the superfluous parameter list | |||
// introduced by the ON/EXPECT_CALL macros. See the macro comments for more | // introduced by the ON/EXPECT_CALL macros. See the macro comments for more | |||
// explanation. | // explanation. | |||
MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) { | MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) { | |||
return *this; | return *this; | |||
} | } | |||
private: | private: | |||
skipping to change at line 1318 | skipping to change at line 1315 | |||
// T is a move-only value type (which means that it will always be copyable | // T is a move-only value type (which means that it will always be copyable | |||
// if the current platform does not support move semantics). | // if the current platform does not support move semantics). | |||
// | // | |||
// The primary template defines handling for values, but function header | // The primary template defines handling for values, but function header | |||
// comments describe the contract for the whole template (including | // comments describe the contract for the whole template (including | |||
// specializations). | // specializations). | |||
template <typename T> | template <typename T> | |||
class ReferenceOrValueWrapper { | class ReferenceOrValueWrapper { | |||
public: | public: | |||
// Constructs a wrapper from the given value/reference. | // Constructs a wrapper from the given value/reference. | |||
explicit ReferenceOrValueWrapper(T value) | explicit ReferenceOrValueWrapper(T value) : value_(std::move(value)) {} | |||
: value_(std::move(value)) { | ||||
} | ||||
// Unwraps and returns the underlying value/reference, exactly as | // Unwraps and returns the underlying value/reference, exactly as | |||
// originally passed. The behavior of calling this more than once on | // originally passed. The behavior of calling this more than once on | |||
// the same object is unspecified. | // the same object is unspecified. | |||
T Unwrap() { return std::move(value_); } | T Unwrap() { return std::move(value_); } | |||
// Provides nondestructive access to the underlying value/reference. | // Provides nondestructive access to the underlying value/reference. | |||
// Always returns a const reference (more precisely, | // Always returns a const reference (more precisely, | |||
// const std::add_lvalue_reference<T>::type). The behavior of calling this | // const std::add_lvalue_reference<T>::type). The behavior of calling this | |||
// after calling Unwrap on the same object is unspecified. | // after calling Unwrap on the same object is unspecified. | |||
const T& Peek() const { | const T& Peek() const { return value_; } | |||
return value_; | ||||
} | ||||
private: | private: | |||
T value_; | T value_; | |||
}; | }; | |||
// Specialization for lvalue reference types. See primary template | // Specialization for lvalue reference types. See primary template | |||
// for documentation. | // for documentation. | |||
template <typename T> | template <typename T> | |||
class ReferenceOrValueWrapper<T&> { | class ReferenceOrValueWrapper<T&> { | |||
public: | public: | |||
// Workaround for debatable pass-by-reference lint warning (c-library-team | // Workaround for debatable pass-by-reference lint warning (c-library-team | |||
// policy precludes NOLINT in this context) | // policy precludes NOLINT in this context) | |||
typedef T& reference; | typedef T& reference; | |||
explicit ReferenceOrValueWrapper(reference ref) | explicit ReferenceOrValueWrapper(reference ref) : value_ptr_(&ref) {} | |||
: value_ptr_(&ref) {} | ||||
T& Unwrap() { return *value_ptr_; } | T& Unwrap() { return *value_ptr_; } | |||
const T& Peek() const { return *value_ptr_; } | const T& Peek() const { return *value_ptr_; } | |||
private: | private: | |||
T* value_ptr_; | T* value_ptr_; | |||
}; | }; | |||
// C++ treats the void type specially. For example, you cannot define | // Prints the held value as an action's result to os. | |||
// 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. | ||||
template <typename T> | template <typename T> | |||
class ActionResultHolder : public UntypedActionResultHolderBase { | void PrintAsActionResult(const T& result, std::ostream& os) { | |||
public: | os << "\n Returns: "; | |||
// Returns the held value. Must not be called more than once. | // T may be a reference type, so we don't use UniversalPrint(). | |||
T Unwrap() { | UniversalPrinter<T>::Print(result, &os); | |||
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); | ||||
} | ||||
// Performs the given mock function's default action and returns the | // Reports an uninteresting call (whose description is in msg) in the | |||
// result in a new-ed ActionResultHolder. | // manner specified by 'reaction'. | |||
template <typename F> | GTEST_API_ void ReportUninterestingCall(CallReaction reaction, | |||
static ActionResultHolder* PerformDefaultAction( | const std::string& msg); | |||
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))); | ||||
} | ||||
// 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)))); | ||||
} | ||||
private: | ||||
typedef ReferenceOrValueWrapper<T> Wrapper; | ||||
explicit ActionResultHolder(Wrapper result) | ||||
: result_(std::move(result)) { | ||||
} | ||||
Wrapper result_; | ||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder); | ||||
}; | ||||
// Specialization for T = void. | // A generic RAII type that runs a user-provided function in its destructor. | |||
template <> | class Cleanup final { | |||
class ActionResultHolder<void> : public UntypedActionResultHolderBase { | ||||
public: | public: | |||
void Unwrap() { } | explicit Cleanup(std::function<void()> f) : f_(std::move(f)) {} | |||
~Cleanup() { f_(); } | ||||
void PrintAsActionResult(::std::ostream* /* os */) const override {} | ||||
// 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; | ||||
} | ||||
// 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; | ||||
} | ||||
private: | private: | |||
ActionResultHolder() {} | std::function<void()> f_; | |||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder); | ||||
}; | }; | |||
template <typename F> | template <typename F> | |||
class FunctionMocker; | class FunctionMocker; | |||
template <typename R, typename... Args> | template <typename R, typename... Args> | |||
class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase { | class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase { | |||
using F = R(Args...); | using F = R(Args...); | |||
public: | public: | |||
skipping to change at line 1496 | skipping to change at line 1413 | |||
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { | ~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { | |||
MutexLock l(&g_gmock_mutex); | MutexLock l(&g_gmock_mutex); | |||
VerifyAndClearExpectationsLocked(); | VerifyAndClearExpectationsLocked(); | |||
Mock::UnregisterLocked(this); | Mock::UnregisterLocked(this); | |||
ClearDefaultActionsLocked(); | ClearDefaultActionsLocked(); | |||
} | } | |||
// Returns the ON_CALL spec that matches this mock function with the | // Returns the ON_CALL spec that matches this mock function with the | |||
// given arguments; returns NULL if no matching ON_CALL is found. | // given arguments; returns NULL if no matching ON_CALL is found. | |||
// L = * | // L = * | |||
const OnCallSpec<F>* FindOnCallSpec( | const OnCallSpec<F>* FindOnCallSpec(const ArgumentTuple& args) const { | |||
const ArgumentTuple& args) const { | for (UntypedOnCallSpecs::const_reverse_iterator it = | |||
for (UntypedOnCallSpecs::const_reverse_iterator it | untyped_on_call_specs_.rbegin(); | |||
= untyped_on_call_specs_.rbegin(); | ||||
it != untyped_on_call_specs_.rend(); ++it) { | it != untyped_on_call_specs_.rend(); ++it) { | |||
const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it); | const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it); | |||
if (spec->Matches(args)) | if (spec->Matches(args)) return spec; | |||
return spec; | ||||
} | } | |||
return nullptr; | return nullptr; | |||
} | } | |||
// Performs the default action of this mock function on the given | // Performs the default action of this mock function on the given | |||
// arguments and returns the result. Asserts (or throws if | // 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 | // is no valid return value. This method doesn't depend on the | |||
// 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(ArgumentTuple&& args, | Result PerformDefaultAction(ArgumentTuple&& args, | |||
const std::string& call_description) const { | const std::string& call_description) const { | |||
const OnCallSpec<F>* const spec = | const OnCallSpec<F>* const spec = this->FindOnCallSpec(args); | |||
this->FindOnCallSpec(args); | ||||
if (spec != nullptr) { | if (spec != nullptr) { | |||
return spec->GetAction().Perform(std::move(args)); | return spec->GetAction().Perform(std::move(args)); | |||
} | } | |||
const std::string message = | const std::string message = | |||
call_description + | call_description + | |||
"\n The mock function has no default action " | "\n The mock function has no default action " | |||
"set, and its return type has no default value set."; | "set, and its return type has no default value set."; | |||
#if GTEST_HAS_EXCEPTIONS | #if GTEST_HAS_EXCEPTIONS | |||
if (!DefaultValue<Result>::Exists()) { | if (!DefaultValue<Result>::Exists()) { | |||
throw std::runtime_error(message); | throw std::runtime_error(message); | |||
} | } | |||
#else | #else | |||
Assert(DefaultValue<Result>::Exists(), "", -1, message); | Assert(DefaultValue<Result>::Exists(), "", -1, message); | |||
#endif | #endif | |||
return DefaultValue<Result>::Get(); | 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(): | // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): | |||
// clears the ON_CALL()s set on this mock function. | // clears the ON_CALL()s set on this mock function. | |||
void ClearDefaultActionsLocked() override | void ClearDefaultActionsLocked() override | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
// Deleting our default actions may trigger other mock objects to be | // Deleting our default actions may trigger other mock objects to be | |||
// deleted, for example if an action contains a reference counted smart | // deleted, for example if an action contains a reference counted smart | |||
// pointer to that mock object, and that is the last reference. So if we | // pointer to that mock object, and that is the last reference. So if we | |||
// delete our actions within the context of the global mutex we may deadlock | // delete our actions within the context of the global mutex we may deadlock | |||
// when this method is called again. Instead, make a copy of the set of | // when this method is called again. Instead, make a copy of the set of | |||
// actions to delete, clear our set within the mutex, and then delete the | // actions to delete, clear our set within the mutex, and then delete the | |||
// actions outside of the mutex. | // actions outside of the mutex. | |||
UntypedOnCallSpecs specs_to_delete; | UntypedOnCallSpecs specs_to_delete; | |||
untyped_on_call_specs_.swap(specs_to_delete); | untyped_on_call_specs_.swap(specs_to_delete); | |||
g_gmock_mutex.Unlock(); | g_gmock_mutex.Unlock(); | |||
for (UntypedOnCallSpecs::const_iterator it = | for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin(); | |||
specs_to_delete.begin(); | ||||
it != specs_to_delete.end(); ++it) { | it != specs_to_delete.end(); ++it) { | |||
delete static_cast<const OnCallSpec<F>*>(*it); | delete static_cast<const OnCallSpec<F>*>(*it); | |||
} | } | |||
// Lock the mutex again, since the caller expects it to be locked when we | // Lock the mutex again, since the caller expects it to be locked when we | |||
// return. | // return. | |||
g_gmock_mutex.Lock(); | g_gmock_mutex.Lock(); | |||
} | } | |||
// 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 Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { | Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { | |||
ArgumentTuple tuple(std::forward<Args>(args)...); | return InvokeWith(ArgumentTuple(std::forward<Args>(args)...)); | |||
std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>( | ||||
this->UntypedInvokeWith(static_cast<void*>(&tuple)))); | ||||
return holder->Unwrap(); | ||||
} | } | |||
MockSpec<F> With(Matcher<Args>... m) { | MockSpec<F> With(Matcher<Args>... m) { | |||
return MockSpec<F>(this, ::std::make_tuple(std::move(m)...)); | return MockSpec<F>(this, ::std::make_tuple(std::move(m)...)); | |||
} | } | |||
protected: | protected: | |||
template <typename Function> | template <typename Function> | |||
friend class MockSpec; | friend class MockSpec; | |||
typedef ActionResultHolder<Result> ResultHolder; | ||||
// Adds and returns a default action spec for this mock function. | // Adds and returns a default action spec for this mock function. | |||
OnCallSpec<F>& AddNewOnCallSpec( | OnCallSpec<F>& AddNewOnCallSpec(const char* file, int line, | |||
const char* file, int line, | const ArgumentMatcherTuple& m) | |||
const ArgumentMatcherTuple& m) | GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { | |||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { | ||||
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); | Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); | |||
OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m); | OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m); | |||
untyped_on_call_specs_.push_back(on_call_spec); | untyped_on_call_specs_.push_back(on_call_spec); | |||
return *on_call_spec; | return *on_call_spec; | |||
} | } | |||
// Adds and returns an expectation spec for this mock function. | // Adds and returns an expectation spec for this mock function. | |||
TypedExpectation<F>& AddNewExpectation(const char* file, int line, | TypedExpectation<F>& AddNewExpectation(const char* file, int line, | |||
const std::string& source_text, | const std::string& source_text, | |||
const ArgumentMatcherTuple& m) | const ArgumentMatcherTuple& m) | |||
skipping to change at line 1645 | skipping to change at line 1526 | |||
// Adds this expectation into the implicit sequence if there is one. | // Adds this expectation into the implicit sequence if there is one. | |||
Sequence* const implicit_sequence = g_gmock_implicit_sequence.get(); | Sequence* const implicit_sequence = g_gmock_implicit_sequence.get(); | |||
if (implicit_sequence != nullptr) { | if (implicit_sequence != nullptr) { | |||
implicit_sequence->AddExpectation(Expectation(untyped_expectation)); | implicit_sequence->AddExpectation(Expectation(untyped_expectation)); | |||
} | } | |||
return *expectation; | return *expectation; | |||
} | } | |||
private: | private: | |||
template <typename Func> friend class TypedExpectation; | template <typename Func> | |||
friend class TypedExpectation; | ||||
// Some utilities needed for implementing UntypedInvokeWith(). | // Some utilities needed for implementing UntypedInvokeWith(). | |||
// Describes what default action will be performed for the given | // Describes what default action will be performed for the given | |||
// arguments. | // arguments. | |||
// L = * | // L = * | |||
void DescribeDefaultActionTo(const ArgumentTuple& args, | void DescribeDefaultActionTo(const ArgumentTuple& args, | |||
::std::ostream* os) const { | ::std::ostream* os) const { | |||
const OnCallSpec<F>* const spec = FindOnCallSpec(args); | const OnCallSpec<F>* const spec = FindOnCallSpec(args); | |||
skipping to change at line 1729 | skipping to change at line 1611 | |||
// Prints the given function arguments to the ostream. | // Prints the given function arguments to the ostream. | |||
void UntypedPrintArgs(const void* untyped_args, | void UntypedPrintArgs(const void* untyped_args, | |||
::std::ostream* os) const override { | ::std::ostream* os) const override { | |||
const ArgumentTuple& args = | const ArgumentTuple& args = | |||
*static_cast<const ArgumentTuple*>(untyped_args); | *static_cast<const ArgumentTuple*>(untyped_args); | |||
UniversalPrint(args, os); | UniversalPrint(args, os); | |||
} | } | |||
// Returns the expectation that matches the arguments, or NULL if no | // Returns the expectation that matches the arguments, or NULL if no | |||
// expectation matches them. | // expectation matches them. | |||
TypedExpectation<F>* FindMatchingExpectationLocked( | TypedExpectation<F>* FindMatchingExpectationLocked(const ArgumentTuple& args) | |||
const ArgumentTuple& args) const | 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 | // See the definition of untyped_expectations_ for why access to | |||
// it is unprotected here. | // 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) { | |||
TypedExpectation<F>* const exp = | TypedExpectation<F>* const exp = | |||
static_cast<TypedExpectation<F>*>(it->get()); | static_cast<TypedExpectation<F>*>(it->get()); | |||
if (exp->ShouldHandleArguments(args)) { | if (exp->ShouldHandleArguments(args)) { | |||
return exp; | return exp; | |||
} | } | |||
} | } | |||
return nullptr; | return nullptr; | |||
} | } | |||
// Returns a message that the arguments don't match any expectation. | // Returns a message that the arguments don't match any expectation. | |||
void FormatUnexpectedCallMessageLocked( | void FormatUnexpectedCallMessageLocked(const ArgumentTuple& args, | |||
const ArgumentTuple& args, | ::std::ostream* os, | |||
::std::ostream* os, | ::std::ostream* why) const | |||
::std::ostream* why) const | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
*os << "\nUnexpected mock function call - "; | *os << "\nUnexpected mock function call - "; | |||
DescribeDefaultActionTo(args, os); | DescribeDefaultActionTo(args, os); | |||
PrintTriedExpectationsLocked(args, why); | PrintTriedExpectationsLocked(args, why); | |||
} | } | |||
// Prints a list of expectations that have been tried against the | // Prints a list of expectations that have been tried against the | |||
// current mock function call. | // current mock function call. | |||
void PrintTriedExpectationsLocked( | void PrintTriedExpectationsLocked(const ArgumentTuple& args, | |||
const ArgumentTuple& args, | ::std::ostream* why) const | |||
::std::ostream* why) const | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | ||||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
const size_t count = untyped_expectations_.size(); | const size_t count = untyped_expectations_.size(); | |||
*why << "Google Mock tried the following " << count << " " | *why << "Google Mock tried the following " << count << " " | |||
<< (count == 1 ? "expectation, but it didn't match" : | << (count == 1 ? "expectation, but it didn't match" | |||
"expectations, but none matched") | : "expectations, but none matched") | |||
<< ":\n"; | << ":\n"; | |||
for (size_t i = 0; i < count; i++) { | for (size_t i = 0; i < count; i++) { | |||
TypedExpectation<F>* const expectation = | TypedExpectation<F>* const expectation = | |||
static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get()); | static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get()); | |||
*why << "\n"; | *why << "\n"; | |||
expectation->DescribeLocationTo(why); | expectation->DescribeLocationTo(why); | |||
if (count > 1) { | if (count > 1) { | |||
*why << "tried expectation #" << i << ": "; | *why << "tried expectation #" << i << ": "; | |||
} | } | |||
*why << expectation->source_text() << "...\n"; | *why << expectation->source_text() << "...\n"; | |||
expectation->ExplainMatchResultTo(args, why); | expectation->ExplainMatchResultTo(args, why); | |||
expectation->DescribeCallCountTo(why); | 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 | }; // class FunctionMocker | |||
// Reports an uninteresting call (whose description is in msg) in the | // Calculates the result of invoking this mock function with the given | |||
// manner specified by 'reaction'. | // arguments, prints it, and returns it. | |||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg); | 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. | ||||
const Cleanup report_uninteresting_call( | ||||
[&] { ReportUninterestingCall(reaction, ss.str()); }); | ||||
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. | ||||
const Cleanup handle_failures([&] { | ||||
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); | ||||
} | ||||
}); | ||||
return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(), | ||||
ss); | ||||
} | ||||
} // namespace internal | } // namespace internal | |||
namespace internal { | namespace internal { | |||
template <typename F> | template <typename F> | |||
class MockFunction; | class MockFunction; | |||
template <typename R, typename... Args> | template <typename R, typename... Args> | |||
class MockFunction<R(Args...)> { | class MockFunction<R(Args...)> { | |||
skipping to change at line 1953 | skipping to change at line 1998 | |||
// MOCK_METHOD0(Bar, int()); | // MOCK_METHOD0(Bar, int()); | |||
// MOCK_CONST_METHOD0(Bar, int&()); | // MOCK_CONST_METHOD0(Bar, int&()); | |||
// }; | // }; | |||
// | // | |||
// MockFoo foo; | // MockFoo foo; | |||
// // Expects a call to non-const MockFoo::Bar(). | // // Expects a call to non-const MockFoo::Bar(). | |||
// EXPECT_CALL(foo, Bar()); | // EXPECT_CALL(foo, Bar()); | |||
// // Expects a call to const MockFoo::Bar(). | // // Expects a call to const MockFoo::Bar(). | |||
// EXPECT_CALL(Const(foo), Bar()); | // EXPECT_CALL(Const(foo), Bar()); | |||
template <typename T> | 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. | // Constructs an Expectation object that references and co-owns exp. | |||
inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT | inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT | |||
: expectation_base_(exp.GetHandle().expectation_base()) {} | : expectation_base_(exp.GetHandle().expectation_base()) {} | |||
} // namespace testing | } // namespace testing | |||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 | |||
// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is | // Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is | |||
End of changes. 76 change blocks. | ||||
270 lines changed or deleted | 317 lines changed or added |