"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "googlemock/include/gmock/gmock-spec-builders.h" between
googletest-release-1.11.0.tar.gz and googletest-release-1.12.0.tar.gz

About: GoogleTest is Google's (unit) testing and mocking framework for C++ tests.

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

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)