gmock-spec-builders.cc revision 13481
113481Sgiacomo.travaglini@arm.com// Copyright 2007, Google Inc. 213481Sgiacomo.travaglini@arm.com// All rights reserved. 313481Sgiacomo.travaglini@arm.com// 413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without 513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are 613481Sgiacomo.travaglini@arm.com// met: 713481Sgiacomo.travaglini@arm.com// 813481Sgiacomo.travaglini@arm.com// * Redistributions of source code must retain the above copyright 913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer. 1013481Sgiacomo.travaglini@arm.com// * Redistributions in binary form must reproduce the above 1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer 1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the 1313481Sgiacomo.travaglini@arm.com// distribution. 1413481Sgiacomo.travaglini@arm.com// * Neither the name of Google Inc. nor the names of its 1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from 1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission. 1713481Sgiacomo.travaglini@arm.com// 1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2913481Sgiacomo.travaglini@arm.com// 3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan) 3113481Sgiacomo.travaglini@arm.com 3213481Sgiacomo.travaglini@arm.com// Google Mock - a framework for writing C++ mock classes. 3313481Sgiacomo.travaglini@arm.com// 3413481Sgiacomo.travaglini@arm.com// This file implements the spec builder syntax (ON_CALL and 3513481Sgiacomo.travaglini@arm.com// EXPECT_CALL). 3613481Sgiacomo.travaglini@arm.com 3713481Sgiacomo.travaglini@arm.com#include "gmock/gmock-spec-builders.h" 3813481Sgiacomo.travaglini@arm.com 3913481Sgiacomo.travaglini@arm.com#include <stdlib.h> 4013481Sgiacomo.travaglini@arm.com#include <iostream> // NOLINT 4113481Sgiacomo.travaglini@arm.com#include <map> 4213481Sgiacomo.travaglini@arm.com#include <set> 4313481Sgiacomo.travaglini@arm.com#include <string> 4413481Sgiacomo.travaglini@arm.com#include "gmock/gmock.h" 4513481Sgiacomo.travaglini@arm.com#include "gtest/gtest.h" 4613481Sgiacomo.travaglini@arm.com 4713481Sgiacomo.travaglini@arm.com#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC 4813481Sgiacomo.travaglini@arm.com# include <unistd.h> // NOLINT 4913481Sgiacomo.travaglini@arm.com#endif 5013481Sgiacomo.travaglini@arm.com 5113481Sgiacomo.travaglini@arm.comnamespace testing { 5213481Sgiacomo.travaglini@arm.comnamespace internal { 5313481Sgiacomo.travaglini@arm.com 5413481Sgiacomo.travaglini@arm.com// Protects the mock object registry (in class Mock), all function 5513481Sgiacomo.travaglini@arm.com// mockers, and all expectations. 5613481Sgiacomo.travaglini@arm.comGTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); 5713481Sgiacomo.travaglini@arm.com 5813481Sgiacomo.travaglini@arm.com// Logs a message including file and line number information. 5913481Sgiacomo.travaglini@arm.comGTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, 6013481Sgiacomo.travaglini@arm.com const char* file, int line, 6113481Sgiacomo.travaglini@arm.com const string& message) { 6213481Sgiacomo.travaglini@arm.com ::std::ostringstream s; 6313481Sgiacomo.travaglini@arm.com s << file << ":" << line << ": " << message << ::std::endl; 6413481Sgiacomo.travaglini@arm.com Log(severity, s.str(), 0); 6513481Sgiacomo.travaglini@arm.com} 6613481Sgiacomo.travaglini@arm.com 6713481Sgiacomo.travaglini@arm.com// Constructs an ExpectationBase object. 6813481Sgiacomo.travaglini@arm.comExpectationBase::ExpectationBase(const char* a_file, 6913481Sgiacomo.travaglini@arm.com int a_line, 7013481Sgiacomo.travaglini@arm.com const string& a_source_text) 7113481Sgiacomo.travaglini@arm.com : file_(a_file), 7213481Sgiacomo.travaglini@arm.com line_(a_line), 7313481Sgiacomo.travaglini@arm.com source_text_(a_source_text), 7413481Sgiacomo.travaglini@arm.com cardinality_specified_(false), 7513481Sgiacomo.travaglini@arm.com cardinality_(Exactly(1)), 7613481Sgiacomo.travaglini@arm.com call_count_(0), 7713481Sgiacomo.travaglini@arm.com retired_(false), 7813481Sgiacomo.travaglini@arm.com extra_matcher_specified_(false), 7913481Sgiacomo.travaglini@arm.com repeated_action_specified_(false), 8013481Sgiacomo.travaglini@arm.com retires_on_saturation_(false), 8113481Sgiacomo.travaglini@arm.com last_clause_(kNone), 8213481Sgiacomo.travaglini@arm.com action_count_checked_(false) {} 8313481Sgiacomo.travaglini@arm.com 8413481Sgiacomo.travaglini@arm.com// Destructs an ExpectationBase object. 8513481Sgiacomo.travaglini@arm.comExpectationBase::~ExpectationBase() {} 8613481Sgiacomo.travaglini@arm.com 8713481Sgiacomo.travaglini@arm.com// Explicitly specifies the cardinality of this expectation. Used by 8813481Sgiacomo.travaglini@arm.com// the subclasses to implement the .Times() clause. 8913481Sgiacomo.travaglini@arm.comvoid ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) { 9013481Sgiacomo.travaglini@arm.com cardinality_specified_ = true; 9113481Sgiacomo.travaglini@arm.com cardinality_ = a_cardinality; 9213481Sgiacomo.travaglini@arm.com} 9313481Sgiacomo.travaglini@arm.com 9413481Sgiacomo.travaglini@arm.com// Retires all pre-requisites of this expectation. 9513481Sgiacomo.travaglini@arm.comvoid ExpectationBase::RetireAllPreRequisites() 9613481Sgiacomo.travaglini@arm.com GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 9713481Sgiacomo.travaglini@arm.com if (is_retired()) { 9813481Sgiacomo.travaglini@arm.com // We can take this short-cut as we never retire an expectation 9913481Sgiacomo.travaglini@arm.com // until we have retired all its pre-requisites. 10013481Sgiacomo.travaglini@arm.com return; 10113481Sgiacomo.travaglini@arm.com } 10213481Sgiacomo.travaglini@arm.com 10313481Sgiacomo.travaglini@arm.com for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); 10413481Sgiacomo.travaglini@arm.com it != immediate_prerequisites_.end(); ++it) { 10513481Sgiacomo.travaglini@arm.com ExpectationBase* const prerequisite = it->expectation_base().get(); 10613481Sgiacomo.travaglini@arm.com if (!prerequisite->is_retired()) { 10713481Sgiacomo.travaglini@arm.com prerequisite->RetireAllPreRequisites(); 10813481Sgiacomo.travaglini@arm.com prerequisite->Retire(); 10913481Sgiacomo.travaglini@arm.com } 11013481Sgiacomo.travaglini@arm.com } 11113481Sgiacomo.travaglini@arm.com} 11213481Sgiacomo.travaglini@arm.com 11313481Sgiacomo.travaglini@arm.com// Returns true iff all pre-requisites of this expectation have been 11413481Sgiacomo.travaglini@arm.com// satisfied. 11513481Sgiacomo.travaglini@arm.combool ExpectationBase::AllPrerequisitesAreSatisfied() const 11613481Sgiacomo.travaglini@arm.com GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 11713481Sgiacomo.travaglini@arm.com g_gmock_mutex.AssertHeld(); 11813481Sgiacomo.travaglini@arm.com for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); 11913481Sgiacomo.travaglini@arm.com it != immediate_prerequisites_.end(); ++it) { 12013481Sgiacomo.travaglini@arm.com if (!(it->expectation_base()->IsSatisfied()) || 12113481Sgiacomo.travaglini@arm.com !(it->expectation_base()->AllPrerequisitesAreSatisfied())) 12213481Sgiacomo.travaglini@arm.com return false; 12313481Sgiacomo.travaglini@arm.com } 12413481Sgiacomo.travaglini@arm.com return true; 12513481Sgiacomo.travaglini@arm.com} 12613481Sgiacomo.travaglini@arm.com 12713481Sgiacomo.travaglini@arm.com// Adds unsatisfied pre-requisites of this expectation to 'result'. 12813481Sgiacomo.travaglini@arm.comvoid ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const 12913481Sgiacomo.travaglini@arm.com GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 13013481Sgiacomo.travaglini@arm.com g_gmock_mutex.AssertHeld(); 13113481Sgiacomo.travaglini@arm.com for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); 13213481Sgiacomo.travaglini@arm.com it != immediate_prerequisites_.end(); ++it) { 13313481Sgiacomo.travaglini@arm.com if (it->expectation_base()->IsSatisfied()) { 13413481Sgiacomo.travaglini@arm.com // If *it is satisfied and has a call count of 0, some of its 13513481Sgiacomo.travaglini@arm.com // pre-requisites may not be satisfied yet. 13613481Sgiacomo.travaglini@arm.com if (it->expectation_base()->call_count_ == 0) { 13713481Sgiacomo.travaglini@arm.com it->expectation_base()->FindUnsatisfiedPrerequisites(result); 13813481Sgiacomo.travaglini@arm.com } 13913481Sgiacomo.travaglini@arm.com } else { 14013481Sgiacomo.travaglini@arm.com // Now that we know *it is unsatisfied, we are not so interested 14113481Sgiacomo.travaglini@arm.com // in whether its pre-requisites are satisfied. Therefore we 14213481Sgiacomo.travaglini@arm.com // don't recursively call FindUnsatisfiedPrerequisites() here. 14313481Sgiacomo.travaglini@arm.com *result += *it; 14413481Sgiacomo.travaglini@arm.com } 14513481Sgiacomo.travaglini@arm.com } 14613481Sgiacomo.travaglini@arm.com} 14713481Sgiacomo.travaglini@arm.com 14813481Sgiacomo.travaglini@arm.com// Describes how many times a function call matching this 14913481Sgiacomo.travaglini@arm.com// expectation has occurred. 15013481Sgiacomo.travaglini@arm.comvoid ExpectationBase::DescribeCallCountTo(::std::ostream* os) const 15113481Sgiacomo.travaglini@arm.com GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 15213481Sgiacomo.travaglini@arm.com g_gmock_mutex.AssertHeld(); 15313481Sgiacomo.travaglini@arm.com 15413481Sgiacomo.travaglini@arm.com // Describes how many times the function is expected to be called. 15513481Sgiacomo.travaglini@arm.com *os << " Expected: to be "; 15613481Sgiacomo.travaglini@arm.com cardinality().DescribeTo(os); 15713481Sgiacomo.travaglini@arm.com *os << "\n Actual: "; 15813481Sgiacomo.travaglini@arm.com Cardinality::DescribeActualCallCountTo(call_count(), os); 15913481Sgiacomo.travaglini@arm.com 16013481Sgiacomo.travaglini@arm.com // Describes the state of the expectation (e.g. is it satisfied? 16113481Sgiacomo.travaglini@arm.com // is it active?). 16213481Sgiacomo.travaglini@arm.com *os << " - " << (IsOverSaturated() ? "over-saturated" : 16313481Sgiacomo.travaglini@arm.com IsSaturated() ? "saturated" : 16413481Sgiacomo.travaglini@arm.com IsSatisfied() ? "satisfied" : "unsatisfied") 16513481Sgiacomo.travaglini@arm.com << " and " 16613481Sgiacomo.travaglini@arm.com << (is_retired() ? "retired" : "active"); 16713481Sgiacomo.travaglini@arm.com} 16813481Sgiacomo.travaglini@arm.com 16913481Sgiacomo.travaglini@arm.com// Checks the action count (i.e. the number of WillOnce() and 17013481Sgiacomo.travaglini@arm.com// WillRepeatedly() clauses) against the cardinality if this hasn't 17113481Sgiacomo.travaglini@arm.com// been done before. Prints a warning if there are too many or too 17213481Sgiacomo.travaglini@arm.com// few actions. 17313481Sgiacomo.travaglini@arm.comvoid ExpectationBase::CheckActionCountIfNotDone() const 17413481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(mutex_) { 17513481Sgiacomo.travaglini@arm.com bool should_check = false; 17613481Sgiacomo.travaglini@arm.com { 17713481Sgiacomo.travaglini@arm.com MutexLock l(&mutex_); 17813481Sgiacomo.travaglini@arm.com if (!action_count_checked_) { 17913481Sgiacomo.travaglini@arm.com action_count_checked_ = true; 18013481Sgiacomo.travaglini@arm.com should_check = true; 18113481Sgiacomo.travaglini@arm.com } 18213481Sgiacomo.travaglini@arm.com } 18313481Sgiacomo.travaglini@arm.com 18413481Sgiacomo.travaglini@arm.com if (should_check) { 18513481Sgiacomo.travaglini@arm.com if (!cardinality_specified_) { 18613481Sgiacomo.travaglini@arm.com // The cardinality was inferred - no need to check the action 18713481Sgiacomo.travaglini@arm.com // count against it. 18813481Sgiacomo.travaglini@arm.com return; 18913481Sgiacomo.travaglini@arm.com } 19013481Sgiacomo.travaglini@arm.com 19113481Sgiacomo.travaglini@arm.com // The cardinality was explicitly specified. 19213481Sgiacomo.travaglini@arm.com const int action_count = static_cast<int>(untyped_actions_.size()); 19313481Sgiacomo.travaglini@arm.com const int upper_bound = cardinality().ConservativeUpperBound(); 19413481Sgiacomo.travaglini@arm.com const int lower_bound = cardinality().ConservativeLowerBound(); 19513481Sgiacomo.travaglini@arm.com bool too_many; // True if there are too many actions, or false 19613481Sgiacomo.travaglini@arm.com // if there are too few. 19713481Sgiacomo.travaglini@arm.com if (action_count > upper_bound || 19813481Sgiacomo.travaglini@arm.com (action_count == upper_bound && repeated_action_specified_)) { 19913481Sgiacomo.travaglini@arm.com too_many = true; 20013481Sgiacomo.travaglini@arm.com } else if (0 < action_count && action_count < lower_bound && 20113481Sgiacomo.travaglini@arm.com !repeated_action_specified_) { 20213481Sgiacomo.travaglini@arm.com too_many = false; 20313481Sgiacomo.travaglini@arm.com } else { 20413481Sgiacomo.travaglini@arm.com return; 20513481Sgiacomo.travaglini@arm.com } 20613481Sgiacomo.travaglini@arm.com 20713481Sgiacomo.travaglini@arm.com ::std::stringstream ss; 20813481Sgiacomo.travaglini@arm.com DescribeLocationTo(&ss); 20913481Sgiacomo.travaglini@arm.com ss << "Too " << (too_many ? "many" : "few") 21013481Sgiacomo.travaglini@arm.com << " actions specified in " << source_text() << "...\n" 21113481Sgiacomo.travaglini@arm.com << "Expected to be "; 21213481Sgiacomo.travaglini@arm.com cardinality().DescribeTo(&ss); 21313481Sgiacomo.travaglini@arm.com ss << ", but has " << (too_many ? "" : "only ") 21413481Sgiacomo.travaglini@arm.com << action_count << " WillOnce()" 21513481Sgiacomo.travaglini@arm.com << (action_count == 1 ? "" : "s"); 21613481Sgiacomo.travaglini@arm.com if (repeated_action_specified_) { 21713481Sgiacomo.travaglini@arm.com ss << " and a WillRepeatedly()"; 21813481Sgiacomo.travaglini@arm.com } 21913481Sgiacomo.travaglini@arm.com ss << "."; 22013481Sgiacomo.travaglini@arm.com Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace". 22113481Sgiacomo.travaglini@arm.com } 22213481Sgiacomo.travaglini@arm.com} 22313481Sgiacomo.travaglini@arm.com 22413481Sgiacomo.travaglini@arm.com// Implements the .Times() clause. 22513481Sgiacomo.travaglini@arm.comvoid ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { 22613481Sgiacomo.travaglini@arm.com if (last_clause_ == kTimes) { 22713481Sgiacomo.travaglini@arm.com ExpectSpecProperty(false, 22813481Sgiacomo.travaglini@arm.com ".Times() cannot appear " 22913481Sgiacomo.travaglini@arm.com "more than once in an EXPECT_CALL()."); 23013481Sgiacomo.travaglini@arm.com } else { 23113481Sgiacomo.travaglini@arm.com ExpectSpecProperty(last_clause_ < kTimes, 23213481Sgiacomo.travaglini@arm.com ".Times() cannot appear after " 23313481Sgiacomo.travaglini@arm.com ".InSequence(), .WillOnce(), .WillRepeatedly(), " 23413481Sgiacomo.travaglini@arm.com "or .RetiresOnSaturation()."); 23513481Sgiacomo.travaglini@arm.com } 23613481Sgiacomo.travaglini@arm.com last_clause_ = kTimes; 23713481Sgiacomo.travaglini@arm.com 23813481Sgiacomo.travaglini@arm.com SpecifyCardinality(a_cardinality); 23913481Sgiacomo.travaglini@arm.com} 24013481Sgiacomo.travaglini@arm.com 24113481Sgiacomo.travaglini@arm.com// Points to the implicit sequence introduced by a living InSequence 24213481Sgiacomo.travaglini@arm.com// object (if any) in the current thread or NULL. 24313481Sgiacomo.travaglini@arm.comGTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence; 24413481Sgiacomo.travaglini@arm.com 24513481Sgiacomo.travaglini@arm.com// Reports an uninteresting call (whose description is in msg) in the 24613481Sgiacomo.travaglini@arm.com// manner specified by 'reaction'. 24713481Sgiacomo.travaglini@arm.comvoid ReportUninterestingCall(CallReaction reaction, const string& msg) { 24813481Sgiacomo.travaglini@arm.com // Include a stack trace only if --gmock_verbose=info is specified. 24913481Sgiacomo.travaglini@arm.com const int stack_frames_to_skip = 25013481Sgiacomo.travaglini@arm.com GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1; 25113481Sgiacomo.travaglini@arm.com switch (reaction) { 25213481Sgiacomo.travaglini@arm.com case kAllow: 25313481Sgiacomo.travaglini@arm.com Log(kInfo, msg, stack_frames_to_skip); 25413481Sgiacomo.travaglini@arm.com break; 25513481Sgiacomo.travaglini@arm.com case kWarn: 25613481Sgiacomo.travaglini@arm.com Log(kWarning, 25713481Sgiacomo.travaglini@arm.com msg + 25813481Sgiacomo.travaglini@arm.com "\nNOTE: You can safely ignore the above warning unless this " 25913481Sgiacomo.travaglini@arm.com "call should not happen. Do not suppress it by blindly adding " 26013481Sgiacomo.travaglini@arm.com "an EXPECT_CALL() if you don't mean to enforce the call. " 26113481Sgiacomo.travaglini@arm.com "See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#" 26213481Sgiacomo.travaglini@arm.com "knowing-when-to-expect for details.\n", 26313481Sgiacomo.travaglini@arm.com stack_frames_to_skip); 26413481Sgiacomo.travaglini@arm.com break; 26513481Sgiacomo.travaglini@arm.com default: // FAIL 26613481Sgiacomo.travaglini@arm.com Expect(false, NULL, -1, msg); 26713481Sgiacomo.travaglini@arm.com } 26813481Sgiacomo.travaglini@arm.com} 26913481Sgiacomo.travaglini@arm.com 27013481Sgiacomo.travaglini@arm.comUntypedFunctionMockerBase::UntypedFunctionMockerBase() 27113481Sgiacomo.travaglini@arm.com : mock_obj_(NULL), name_("") {} 27213481Sgiacomo.travaglini@arm.com 27313481Sgiacomo.travaglini@arm.comUntypedFunctionMockerBase::~UntypedFunctionMockerBase() {} 27413481Sgiacomo.travaglini@arm.com 27513481Sgiacomo.travaglini@arm.com// Sets the mock object this mock method belongs to, and registers 27613481Sgiacomo.travaglini@arm.com// this information in the global mock registry. Will be called 27713481Sgiacomo.travaglini@arm.com// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock 27813481Sgiacomo.travaglini@arm.com// method. 27913481Sgiacomo.travaglini@arm.comvoid UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) 28013481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 28113481Sgiacomo.travaglini@arm.com { 28213481Sgiacomo.travaglini@arm.com MutexLock l(&g_gmock_mutex); 28313481Sgiacomo.travaglini@arm.com mock_obj_ = mock_obj; 28413481Sgiacomo.travaglini@arm.com } 28513481Sgiacomo.travaglini@arm.com Mock::Register(mock_obj, this); 28613481Sgiacomo.travaglini@arm.com} 28713481Sgiacomo.travaglini@arm.com 28813481Sgiacomo.travaglini@arm.com// Sets the mock object this mock method belongs to, and sets the name 28913481Sgiacomo.travaglini@arm.com// of the mock function. Will be called upon each invocation of this 29013481Sgiacomo.travaglini@arm.com// mock function. 29113481Sgiacomo.travaglini@arm.comvoid UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj, 29213481Sgiacomo.travaglini@arm.com const char* name) 29313481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 29413481Sgiacomo.travaglini@arm.com // We protect name_ under g_gmock_mutex in case this mock function 29513481Sgiacomo.travaglini@arm.com // is called from two threads concurrently. 29613481Sgiacomo.travaglini@arm.com MutexLock l(&g_gmock_mutex); 29713481Sgiacomo.travaglini@arm.com mock_obj_ = mock_obj; 29813481Sgiacomo.travaglini@arm.com name_ = name; 29913481Sgiacomo.travaglini@arm.com} 30013481Sgiacomo.travaglini@arm.com 30113481Sgiacomo.travaglini@arm.com// Returns the name of the function being mocked. Must be called 30213481Sgiacomo.travaglini@arm.com// after RegisterOwner() or SetOwnerAndName() has been called. 30313481Sgiacomo.travaglini@arm.comconst void* UntypedFunctionMockerBase::MockObject() const 30413481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 30513481Sgiacomo.travaglini@arm.com const void* mock_obj; 30613481Sgiacomo.travaglini@arm.com { 30713481Sgiacomo.travaglini@arm.com // We protect mock_obj_ under g_gmock_mutex in case this mock 30813481Sgiacomo.travaglini@arm.com // function is called from two threads concurrently. 30913481Sgiacomo.travaglini@arm.com MutexLock l(&g_gmock_mutex); 31013481Sgiacomo.travaglini@arm.com Assert(mock_obj_ != NULL, __FILE__, __LINE__, 31113481Sgiacomo.travaglini@arm.com "MockObject() must not be called before RegisterOwner() or " 31213481Sgiacomo.travaglini@arm.com "SetOwnerAndName() has been called."); 31313481Sgiacomo.travaglini@arm.com mock_obj = mock_obj_; 31413481Sgiacomo.travaglini@arm.com } 31513481Sgiacomo.travaglini@arm.com return mock_obj; 31613481Sgiacomo.travaglini@arm.com} 31713481Sgiacomo.travaglini@arm.com 31813481Sgiacomo.travaglini@arm.com// Returns the name of this mock method. Must be called after 31913481Sgiacomo.travaglini@arm.com// SetOwnerAndName() has been called. 32013481Sgiacomo.travaglini@arm.comconst char* UntypedFunctionMockerBase::Name() const 32113481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 32213481Sgiacomo.travaglini@arm.com const char* name; 32313481Sgiacomo.travaglini@arm.com { 32413481Sgiacomo.travaglini@arm.com // We protect name_ under g_gmock_mutex in case this mock 32513481Sgiacomo.travaglini@arm.com // function is called from two threads concurrently. 32613481Sgiacomo.travaglini@arm.com MutexLock l(&g_gmock_mutex); 32713481Sgiacomo.travaglini@arm.com Assert(name_ != NULL, __FILE__, __LINE__, 32813481Sgiacomo.travaglini@arm.com "Name() must not be called before SetOwnerAndName() has " 32913481Sgiacomo.travaglini@arm.com "been called."); 33013481Sgiacomo.travaglini@arm.com name = name_; 33113481Sgiacomo.travaglini@arm.com } 33213481Sgiacomo.travaglini@arm.com return name; 33313481Sgiacomo.travaglini@arm.com} 33413481Sgiacomo.travaglini@arm.com 33513481Sgiacomo.travaglini@arm.com// Calculates the result of invoking this mock function with the given 33613481Sgiacomo.travaglini@arm.com// arguments, prints it, and returns it. The caller is responsible 33713481Sgiacomo.travaglini@arm.com// for deleting the result. 33813481Sgiacomo.travaglini@arm.comUntypedActionResultHolderBase* 33913481Sgiacomo.travaglini@arm.comUntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) 34013481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 34113481Sgiacomo.travaglini@arm.com if (untyped_expectations_.size() == 0) { 34213481Sgiacomo.travaglini@arm.com // No expectation is set on this mock method - we have an 34313481Sgiacomo.travaglini@arm.com // uninteresting call. 34413481Sgiacomo.travaglini@arm.com 34513481Sgiacomo.travaglini@arm.com // We must get Google Mock's reaction on uninteresting calls 34613481Sgiacomo.travaglini@arm.com // made on this mock object BEFORE performing the action, 34713481Sgiacomo.travaglini@arm.com // because the action may DELETE the mock object and make the 34813481Sgiacomo.travaglini@arm.com // following expression meaningless. 34913481Sgiacomo.travaglini@arm.com const CallReaction reaction = 35013481Sgiacomo.travaglini@arm.com Mock::GetReactionOnUninterestingCalls(MockObject()); 35113481Sgiacomo.travaglini@arm.com 35213481Sgiacomo.travaglini@arm.com // True iff we need to print this call's arguments and return 35313481Sgiacomo.travaglini@arm.com // value. This definition must be kept in sync with 35413481Sgiacomo.travaglini@arm.com // the behavior of ReportUninterestingCall(). 35513481Sgiacomo.travaglini@arm.com const bool need_to_report_uninteresting_call = 35613481Sgiacomo.travaglini@arm.com // If the user allows this uninteresting call, we print it 35713481Sgiacomo.travaglini@arm.com // only when he wants informational messages. 35813481Sgiacomo.travaglini@arm.com reaction == kAllow ? LogIsVisible(kInfo) : 35913481Sgiacomo.travaglini@arm.com // If the user wants this to be a warning, we print it only 36013481Sgiacomo.travaglini@arm.com // when he wants to see warnings. 36113481Sgiacomo.travaglini@arm.com reaction == kWarn ? LogIsVisible(kWarning) : 36213481Sgiacomo.travaglini@arm.com // Otherwise, the user wants this to be an error, and we 36313481Sgiacomo.travaglini@arm.com // should always print detailed information in the error. 36413481Sgiacomo.travaglini@arm.com true; 36513481Sgiacomo.travaglini@arm.com 36613481Sgiacomo.travaglini@arm.com if (!need_to_report_uninteresting_call) { 36713481Sgiacomo.travaglini@arm.com // Perform the action without printing the call information. 36813481Sgiacomo.travaglini@arm.com return this->UntypedPerformDefaultAction(untyped_args, ""); 36913481Sgiacomo.travaglini@arm.com } 37013481Sgiacomo.travaglini@arm.com 37113481Sgiacomo.travaglini@arm.com // Warns about the uninteresting call. 37213481Sgiacomo.travaglini@arm.com ::std::stringstream ss; 37313481Sgiacomo.travaglini@arm.com this->UntypedDescribeUninterestingCall(untyped_args, &ss); 37413481Sgiacomo.travaglini@arm.com 37513481Sgiacomo.travaglini@arm.com // Calculates the function result. 37613481Sgiacomo.travaglini@arm.com UntypedActionResultHolderBase* const result = 37713481Sgiacomo.travaglini@arm.com this->UntypedPerformDefaultAction(untyped_args, ss.str()); 37813481Sgiacomo.travaglini@arm.com 37913481Sgiacomo.travaglini@arm.com // Prints the function result. 38013481Sgiacomo.travaglini@arm.com if (result != NULL) 38113481Sgiacomo.travaglini@arm.com result->PrintAsActionResult(&ss); 38213481Sgiacomo.travaglini@arm.com 38313481Sgiacomo.travaglini@arm.com ReportUninterestingCall(reaction, ss.str()); 38413481Sgiacomo.travaglini@arm.com return result; 38513481Sgiacomo.travaglini@arm.com } 38613481Sgiacomo.travaglini@arm.com 38713481Sgiacomo.travaglini@arm.com bool is_excessive = false; 38813481Sgiacomo.travaglini@arm.com ::std::stringstream ss; 38913481Sgiacomo.travaglini@arm.com ::std::stringstream why; 39013481Sgiacomo.travaglini@arm.com ::std::stringstream loc; 39113481Sgiacomo.travaglini@arm.com const void* untyped_action = NULL; 39213481Sgiacomo.travaglini@arm.com 39313481Sgiacomo.travaglini@arm.com // The UntypedFindMatchingExpectation() function acquires and 39413481Sgiacomo.travaglini@arm.com // releases g_gmock_mutex. 39513481Sgiacomo.travaglini@arm.com const ExpectationBase* const untyped_expectation = 39613481Sgiacomo.travaglini@arm.com this->UntypedFindMatchingExpectation( 39713481Sgiacomo.travaglini@arm.com untyped_args, &untyped_action, &is_excessive, 39813481Sgiacomo.travaglini@arm.com &ss, &why); 39913481Sgiacomo.travaglini@arm.com const bool found = untyped_expectation != NULL; 40013481Sgiacomo.travaglini@arm.com 40113481Sgiacomo.travaglini@arm.com // True iff we need to print the call's arguments and return value. 40213481Sgiacomo.travaglini@arm.com // This definition must be kept in sync with the uses of Expect() 40313481Sgiacomo.travaglini@arm.com // and Log() in this function. 40413481Sgiacomo.travaglini@arm.com const bool need_to_report_call = 40513481Sgiacomo.travaglini@arm.com !found || is_excessive || LogIsVisible(kInfo); 40613481Sgiacomo.travaglini@arm.com if (!need_to_report_call) { 40713481Sgiacomo.travaglini@arm.com // Perform the action without printing the call information. 40813481Sgiacomo.travaglini@arm.com return 40913481Sgiacomo.travaglini@arm.com untyped_action == NULL ? 41013481Sgiacomo.travaglini@arm.com this->UntypedPerformDefaultAction(untyped_args, "") : 41113481Sgiacomo.travaglini@arm.com this->UntypedPerformAction(untyped_action, untyped_args); 41213481Sgiacomo.travaglini@arm.com } 41313481Sgiacomo.travaglini@arm.com 41413481Sgiacomo.travaglini@arm.com ss << " Function call: " << Name(); 41513481Sgiacomo.travaglini@arm.com this->UntypedPrintArgs(untyped_args, &ss); 41613481Sgiacomo.travaglini@arm.com 41713481Sgiacomo.travaglini@arm.com // In case the action deletes a piece of the expectation, we 41813481Sgiacomo.travaglini@arm.com // generate the message beforehand. 41913481Sgiacomo.travaglini@arm.com if (found && !is_excessive) { 42013481Sgiacomo.travaglini@arm.com untyped_expectation->DescribeLocationTo(&loc); 42113481Sgiacomo.travaglini@arm.com } 42213481Sgiacomo.travaglini@arm.com 42313481Sgiacomo.travaglini@arm.com UntypedActionResultHolderBase* const result = 42413481Sgiacomo.travaglini@arm.com untyped_action == NULL ? 42513481Sgiacomo.travaglini@arm.com this->UntypedPerformDefaultAction(untyped_args, ss.str()) : 42613481Sgiacomo.travaglini@arm.com this->UntypedPerformAction(untyped_action, untyped_args); 42713481Sgiacomo.travaglini@arm.com if (result != NULL) 42813481Sgiacomo.travaglini@arm.com result->PrintAsActionResult(&ss); 42913481Sgiacomo.travaglini@arm.com ss << "\n" << why.str(); 43013481Sgiacomo.travaglini@arm.com 43113481Sgiacomo.travaglini@arm.com if (!found) { 43213481Sgiacomo.travaglini@arm.com // No expectation matches this call - reports a failure. 43313481Sgiacomo.travaglini@arm.com Expect(false, NULL, -1, ss.str()); 43413481Sgiacomo.travaglini@arm.com } else if (is_excessive) { 43513481Sgiacomo.travaglini@arm.com // We had an upper-bound violation and the failure message is in ss. 43613481Sgiacomo.travaglini@arm.com Expect(false, untyped_expectation->file(), 43713481Sgiacomo.travaglini@arm.com untyped_expectation->line(), ss.str()); 43813481Sgiacomo.travaglini@arm.com } else { 43913481Sgiacomo.travaglini@arm.com // We had an expected call and the matching expectation is 44013481Sgiacomo.travaglini@arm.com // described in ss. 44113481Sgiacomo.travaglini@arm.com Log(kInfo, loc.str() + ss.str(), 2); 44213481Sgiacomo.travaglini@arm.com } 44313481Sgiacomo.travaglini@arm.com 44413481Sgiacomo.travaglini@arm.com return result; 44513481Sgiacomo.travaglini@arm.com} 44613481Sgiacomo.travaglini@arm.com 44713481Sgiacomo.travaglini@arm.com// Returns an Expectation object that references and co-owns exp, 44813481Sgiacomo.travaglini@arm.com// which must be an expectation on this mock function. 44913481Sgiacomo.travaglini@arm.comExpectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { 45013481Sgiacomo.travaglini@arm.com for (UntypedExpectations::const_iterator it = 45113481Sgiacomo.travaglini@arm.com untyped_expectations_.begin(); 45213481Sgiacomo.travaglini@arm.com it != untyped_expectations_.end(); ++it) { 45313481Sgiacomo.travaglini@arm.com if (it->get() == exp) { 45413481Sgiacomo.travaglini@arm.com return Expectation(*it); 45513481Sgiacomo.travaglini@arm.com } 45613481Sgiacomo.travaglini@arm.com } 45713481Sgiacomo.travaglini@arm.com 45813481Sgiacomo.travaglini@arm.com Assert(false, __FILE__, __LINE__, "Cannot find expectation."); 45913481Sgiacomo.travaglini@arm.com return Expectation(); 46013481Sgiacomo.travaglini@arm.com // The above statement is just to make the code compile, and will 46113481Sgiacomo.travaglini@arm.com // never be executed. 46213481Sgiacomo.travaglini@arm.com} 46313481Sgiacomo.travaglini@arm.com 46413481Sgiacomo.travaglini@arm.com// Verifies that all expectations on this mock function have been 46513481Sgiacomo.travaglini@arm.com// satisfied. Reports one or more Google Test non-fatal failures 46613481Sgiacomo.travaglini@arm.com// and returns false if not. 46713481Sgiacomo.travaglini@arm.combool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() 46813481Sgiacomo.travaglini@arm.com GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 46913481Sgiacomo.travaglini@arm.com g_gmock_mutex.AssertHeld(); 47013481Sgiacomo.travaglini@arm.com bool expectations_met = true; 47113481Sgiacomo.travaglini@arm.com for (UntypedExpectations::const_iterator it = 47213481Sgiacomo.travaglini@arm.com untyped_expectations_.begin(); 47313481Sgiacomo.travaglini@arm.com it != untyped_expectations_.end(); ++it) { 47413481Sgiacomo.travaglini@arm.com ExpectationBase* const untyped_expectation = it->get(); 47513481Sgiacomo.travaglini@arm.com if (untyped_expectation->IsOverSaturated()) { 47613481Sgiacomo.travaglini@arm.com // There was an upper-bound violation. Since the error was 47713481Sgiacomo.travaglini@arm.com // already reported when it occurred, there is no need to do 47813481Sgiacomo.travaglini@arm.com // anything here. 47913481Sgiacomo.travaglini@arm.com expectations_met = false; 48013481Sgiacomo.travaglini@arm.com } else if (!untyped_expectation->IsSatisfied()) { 48113481Sgiacomo.travaglini@arm.com expectations_met = false; 48213481Sgiacomo.travaglini@arm.com ::std::stringstream ss; 48313481Sgiacomo.travaglini@arm.com ss << "Actual function call count doesn't match " 48413481Sgiacomo.travaglini@arm.com << untyped_expectation->source_text() << "...\n"; 48513481Sgiacomo.travaglini@arm.com // No need to show the source file location of the expectation 48613481Sgiacomo.travaglini@arm.com // in the description, as the Expect() call that follows already 48713481Sgiacomo.travaglini@arm.com // takes care of it. 48813481Sgiacomo.travaglini@arm.com untyped_expectation->MaybeDescribeExtraMatcherTo(&ss); 48913481Sgiacomo.travaglini@arm.com untyped_expectation->DescribeCallCountTo(&ss); 49013481Sgiacomo.travaglini@arm.com Expect(false, untyped_expectation->file(), 49113481Sgiacomo.travaglini@arm.com untyped_expectation->line(), ss.str()); 49213481Sgiacomo.travaglini@arm.com } 49313481Sgiacomo.travaglini@arm.com } 49413481Sgiacomo.travaglini@arm.com 49513481Sgiacomo.travaglini@arm.com // Deleting our expectations may trigger other mock objects to be deleted, for 49613481Sgiacomo.travaglini@arm.com // example if an action contains a reference counted smart pointer to that 49713481Sgiacomo.travaglini@arm.com // mock object, and that is the last reference. So if we delete our 49813481Sgiacomo.travaglini@arm.com // expectations within the context of the global mutex we may deadlock when 49913481Sgiacomo.travaglini@arm.com // this method is called again. Instead, make a copy of the set of 50013481Sgiacomo.travaglini@arm.com // expectations to delete, clear our set within the mutex, and then clear the 50113481Sgiacomo.travaglini@arm.com // copied set outside of it. 50213481Sgiacomo.travaglini@arm.com UntypedExpectations expectations_to_delete; 50313481Sgiacomo.travaglini@arm.com untyped_expectations_.swap(expectations_to_delete); 50413481Sgiacomo.travaglini@arm.com 50513481Sgiacomo.travaglini@arm.com g_gmock_mutex.Unlock(); 50613481Sgiacomo.travaglini@arm.com expectations_to_delete.clear(); 50713481Sgiacomo.travaglini@arm.com g_gmock_mutex.Lock(); 50813481Sgiacomo.travaglini@arm.com 50913481Sgiacomo.travaglini@arm.com return expectations_met; 51013481Sgiacomo.travaglini@arm.com} 51113481Sgiacomo.travaglini@arm.com 51213481Sgiacomo.travaglini@arm.com} // namespace internal 51313481Sgiacomo.travaglini@arm.com 51413481Sgiacomo.travaglini@arm.com// Class Mock. 51513481Sgiacomo.travaglini@arm.com 51613481Sgiacomo.travaglini@arm.comnamespace { 51713481Sgiacomo.travaglini@arm.com 51813481Sgiacomo.travaglini@arm.comtypedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers; 51913481Sgiacomo.travaglini@arm.com 52013481Sgiacomo.travaglini@arm.com// The current state of a mock object. Such information is needed for 52113481Sgiacomo.travaglini@arm.com// detecting leaked mock objects and explicitly verifying a mock's 52213481Sgiacomo.travaglini@arm.com// expectations. 52313481Sgiacomo.travaglini@arm.comstruct MockObjectState { 52413481Sgiacomo.travaglini@arm.com MockObjectState() 52513481Sgiacomo.travaglini@arm.com : first_used_file(NULL), first_used_line(-1), leakable(false) {} 52613481Sgiacomo.travaglini@arm.com 52713481Sgiacomo.travaglini@arm.com // Where in the source file an ON_CALL or EXPECT_CALL is first 52813481Sgiacomo.travaglini@arm.com // invoked on this mock object. 52913481Sgiacomo.travaglini@arm.com const char* first_used_file; 53013481Sgiacomo.travaglini@arm.com int first_used_line; 53113481Sgiacomo.travaglini@arm.com ::std::string first_used_test_case; 53213481Sgiacomo.travaglini@arm.com ::std::string first_used_test; 53313481Sgiacomo.travaglini@arm.com bool leakable; // true iff it's OK to leak the object. 53413481Sgiacomo.travaglini@arm.com FunctionMockers function_mockers; // All registered methods of the object. 53513481Sgiacomo.travaglini@arm.com}; 53613481Sgiacomo.travaglini@arm.com 53713481Sgiacomo.travaglini@arm.com// A global registry holding the state of all mock objects that are 53813481Sgiacomo.travaglini@arm.com// alive. A mock object is added to this registry the first time 53913481Sgiacomo.travaglini@arm.com// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It 54013481Sgiacomo.travaglini@arm.com// is removed from the registry in the mock object's destructor. 54113481Sgiacomo.travaglini@arm.comclass MockObjectRegistry { 54213481Sgiacomo.travaglini@arm.com public: 54313481Sgiacomo.travaglini@arm.com // Maps a mock object (identified by its address) to its state. 54413481Sgiacomo.travaglini@arm.com typedef std::map<const void*, MockObjectState> StateMap; 54513481Sgiacomo.travaglini@arm.com 54613481Sgiacomo.travaglini@arm.com // This destructor will be called when a program exits, after all 54713481Sgiacomo.travaglini@arm.com // tests in it have been run. By then, there should be no mock 54813481Sgiacomo.travaglini@arm.com // object alive. Therefore we report any living object as test 54913481Sgiacomo.travaglini@arm.com // failure, unless the user explicitly asked us to ignore it. 55013481Sgiacomo.travaglini@arm.com ~MockObjectRegistry() { 55113481Sgiacomo.travaglini@arm.com // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is 55213481Sgiacomo.travaglini@arm.com // a macro. 55313481Sgiacomo.travaglini@arm.com 55413481Sgiacomo.travaglini@arm.com if (!GMOCK_FLAG(catch_leaked_mocks)) 55513481Sgiacomo.travaglini@arm.com return; 55613481Sgiacomo.travaglini@arm.com 55713481Sgiacomo.travaglini@arm.com int leaked_count = 0; 55813481Sgiacomo.travaglini@arm.com for (StateMap::const_iterator it = states_.begin(); it != states_.end(); 55913481Sgiacomo.travaglini@arm.com ++it) { 56013481Sgiacomo.travaglini@arm.com if (it->second.leakable) // The user said it's fine to leak this object. 56113481Sgiacomo.travaglini@arm.com continue; 56213481Sgiacomo.travaglini@arm.com 56313481Sgiacomo.travaglini@arm.com // TODO(wan@google.com): Print the type of the leaked object. 56413481Sgiacomo.travaglini@arm.com // This can help the user identify the leaked object. 56513481Sgiacomo.travaglini@arm.com std::cout << "\n"; 56613481Sgiacomo.travaglini@arm.com const MockObjectState& state = it->second; 56713481Sgiacomo.travaglini@arm.com std::cout << internal::FormatFileLocation(state.first_used_file, 56813481Sgiacomo.travaglini@arm.com state.first_used_line); 56913481Sgiacomo.travaglini@arm.com std::cout << " ERROR: this mock object"; 57013481Sgiacomo.travaglini@arm.com if (state.first_used_test != "") { 57113481Sgiacomo.travaglini@arm.com std::cout << " (used in test " << state.first_used_test_case << "." 57213481Sgiacomo.travaglini@arm.com << state.first_used_test << ")"; 57313481Sgiacomo.travaglini@arm.com } 57413481Sgiacomo.travaglini@arm.com std::cout << " should be deleted but never is. Its address is @" 57513481Sgiacomo.travaglini@arm.com << it->first << "."; 57613481Sgiacomo.travaglini@arm.com leaked_count++; 57713481Sgiacomo.travaglini@arm.com } 57813481Sgiacomo.travaglini@arm.com if (leaked_count > 0) { 57913481Sgiacomo.travaglini@arm.com std::cout << "\nERROR: " << leaked_count 58013481Sgiacomo.travaglini@arm.com << " leaked mock " << (leaked_count == 1 ? "object" : "objects") 58113481Sgiacomo.travaglini@arm.com << " found at program exit.\n"; 58213481Sgiacomo.travaglini@arm.com std::cout.flush(); 58313481Sgiacomo.travaglini@arm.com ::std::cerr.flush(); 58413481Sgiacomo.travaglini@arm.com // RUN_ALL_TESTS() has already returned when this destructor is 58513481Sgiacomo.travaglini@arm.com // called. Therefore we cannot use the normal Google Test 58613481Sgiacomo.travaglini@arm.com // failure reporting mechanism. 58713481Sgiacomo.travaglini@arm.com _exit(1); // We cannot call exit() as it is not reentrant and 58813481Sgiacomo.travaglini@arm.com // may already have been called. 58913481Sgiacomo.travaglini@arm.com } 59013481Sgiacomo.travaglini@arm.com } 59113481Sgiacomo.travaglini@arm.com 59213481Sgiacomo.travaglini@arm.com StateMap& states() { return states_; } 59313481Sgiacomo.travaglini@arm.com 59413481Sgiacomo.travaglini@arm.com private: 59513481Sgiacomo.travaglini@arm.com StateMap states_; 59613481Sgiacomo.travaglini@arm.com}; 59713481Sgiacomo.travaglini@arm.com 59813481Sgiacomo.travaglini@arm.com// Protected by g_gmock_mutex. 59913481Sgiacomo.travaglini@arm.comMockObjectRegistry g_mock_object_registry; 60013481Sgiacomo.travaglini@arm.com 60113481Sgiacomo.travaglini@arm.com// Maps a mock object to the reaction Google Mock should have when an 60213481Sgiacomo.travaglini@arm.com// uninteresting method is called. Protected by g_gmock_mutex. 60313481Sgiacomo.travaglini@arm.comstd::map<const void*, internal::CallReaction> g_uninteresting_call_reaction; 60413481Sgiacomo.travaglini@arm.com 60513481Sgiacomo.travaglini@arm.com// Sets the reaction Google Mock should have when an uninteresting 60613481Sgiacomo.travaglini@arm.com// method of the given mock object is called. 60713481Sgiacomo.travaglini@arm.comvoid SetReactionOnUninterestingCalls(const void* mock_obj, 60813481Sgiacomo.travaglini@arm.com internal::CallReaction reaction) 60913481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 61013481Sgiacomo.travaglini@arm.com internal::MutexLock l(&internal::g_gmock_mutex); 61113481Sgiacomo.travaglini@arm.com g_uninteresting_call_reaction[mock_obj] = reaction; 61213481Sgiacomo.travaglini@arm.com} 61313481Sgiacomo.travaglini@arm.com 61413481Sgiacomo.travaglini@arm.com} // namespace 61513481Sgiacomo.travaglini@arm.com 61613481Sgiacomo.travaglini@arm.com// Tells Google Mock to allow uninteresting calls on the given mock 61713481Sgiacomo.travaglini@arm.com// object. 61813481Sgiacomo.travaglini@arm.comvoid Mock::AllowUninterestingCalls(const void* mock_obj) 61913481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 62013481Sgiacomo.travaglini@arm.com SetReactionOnUninterestingCalls(mock_obj, internal::kAllow); 62113481Sgiacomo.travaglini@arm.com} 62213481Sgiacomo.travaglini@arm.com 62313481Sgiacomo.travaglini@arm.com// Tells Google Mock to warn the user about uninteresting calls on the 62413481Sgiacomo.travaglini@arm.com// given mock object. 62513481Sgiacomo.travaglini@arm.comvoid Mock::WarnUninterestingCalls(const void* mock_obj) 62613481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 62713481Sgiacomo.travaglini@arm.com SetReactionOnUninterestingCalls(mock_obj, internal::kWarn); 62813481Sgiacomo.travaglini@arm.com} 62913481Sgiacomo.travaglini@arm.com 63013481Sgiacomo.travaglini@arm.com// Tells Google Mock to fail uninteresting calls on the given mock 63113481Sgiacomo.travaglini@arm.com// object. 63213481Sgiacomo.travaglini@arm.comvoid Mock::FailUninterestingCalls(const void* mock_obj) 63313481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 63413481Sgiacomo.travaglini@arm.com SetReactionOnUninterestingCalls(mock_obj, internal::kFail); 63513481Sgiacomo.travaglini@arm.com} 63613481Sgiacomo.travaglini@arm.com 63713481Sgiacomo.travaglini@arm.com// Tells Google Mock the given mock object is being destroyed and its 63813481Sgiacomo.travaglini@arm.com// entry in the call-reaction table should be removed. 63913481Sgiacomo.travaglini@arm.comvoid Mock::UnregisterCallReaction(const void* mock_obj) 64013481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 64113481Sgiacomo.travaglini@arm.com internal::MutexLock l(&internal::g_gmock_mutex); 64213481Sgiacomo.travaglini@arm.com g_uninteresting_call_reaction.erase(mock_obj); 64313481Sgiacomo.travaglini@arm.com} 64413481Sgiacomo.travaglini@arm.com 64513481Sgiacomo.travaglini@arm.com// Returns the reaction Google Mock will have on uninteresting calls 64613481Sgiacomo.travaglini@arm.com// made on the given mock object. 64713481Sgiacomo.travaglini@arm.cominternal::CallReaction Mock::GetReactionOnUninterestingCalls( 64813481Sgiacomo.travaglini@arm.com const void* mock_obj) 64913481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 65013481Sgiacomo.travaglini@arm.com internal::MutexLock l(&internal::g_gmock_mutex); 65113481Sgiacomo.travaglini@arm.com return (g_uninteresting_call_reaction.count(mock_obj) == 0) ? 65213481Sgiacomo.travaglini@arm.com internal::kDefault : g_uninteresting_call_reaction[mock_obj]; 65313481Sgiacomo.travaglini@arm.com} 65413481Sgiacomo.travaglini@arm.com 65513481Sgiacomo.travaglini@arm.com// Tells Google Mock to ignore mock_obj when checking for leaked mock 65613481Sgiacomo.travaglini@arm.com// objects. 65713481Sgiacomo.travaglini@arm.comvoid Mock::AllowLeak(const void* mock_obj) 65813481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 65913481Sgiacomo.travaglini@arm.com internal::MutexLock l(&internal::g_gmock_mutex); 66013481Sgiacomo.travaglini@arm.com g_mock_object_registry.states()[mock_obj].leakable = true; 66113481Sgiacomo.travaglini@arm.com} 66213481Sgiacomo.travaglini@arm.com 66313481Sgiacomo.travaglini@arm.com// Verifies and clears all expectations on the given mock object. If 66413481Sgiacomo.travaglini@arm.com// the expectations aren't satisfied, generates one or more Google 66513481Sgiacomo.travaglini@arm.com// Test non-fatal failures and returns false. 66613481Sgiacomo.travaglini@arm.combool Mock::VerifyAndClearExpectations(void* mock_obj) 66713481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 66813481Sgiacomo.travaglini@arm.com internal::MutexLock l(&internal::g_gmock_mutex); 66913481Sgiacomo.travaglini@arm.com return VerifyAndClearExpectationsLocked(mock_obj); 67013481Sgiacomo.travaglini@arm.com} 67113481Sgiacomo.travaglini@arm.com 67213481Sgiacomo.travaglini@arm.com// Verifies all expectations on the given mock object and clears its 67313481Sgiacomo.travaglini@arm.com// default actions and expectations. Returns true iff the 67413481Sgiacomo.travaglini@arm.com// verification was successful. 67513481Sgiacomo.travaglini@arm.combool Mock::VerifyAndClear(void* mock_obj) 67613481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 67713481Sgiacomo.travaglini@arm.com internal::MutexLock l(&internal::g_gmock_mutex); 67813481Sgiacomo.travaglini@arm.com ClearDefaultActionsLocked(mock_obj); 67913481Sgiacomo.travaglini@arm.com return VerifyAndClearExpectationsLocked(mock_obj); 68013481Sgiacomo.travaglini@arm.com} 68113481Sgiacomo.travaglini@arm.com 68213481Sgiacomo.travaglini@arm.com// Verifies and clears all expectations on the given mock object. If 68313481Sgiacomo.travaglini@arm.com// the expectations aren't satisfied, generates one or more Google 68413481Sgiacomo.travaglini@arm.com// Test non-fatal failures and returns false. 68513481Sgiacomo.travaglini@arm.combool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) 68613481Sgiacomo.travaglini@arm.com GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { 68713481Sgiacomo.travaglini@arm.com internal::g_gmock_mutex.AssertHeld(); 68813481Sgiacomo.travaglini@arm.com if (g_mock_object_registry.states().count(mock_obj) == 0) { 68913481Sgiacomo.travaglini@arm.com // No EXPECT_CALL() was set on the given mock object. 69013481Sgiacomo.travaglini@arm.com return true; 69113481Sgiacomo.travaglini@arm.com } 69213481Sgiacomo.travaglini@arm.com 69313481Sgiacomo.travaglini@arm.com // Verifies and clears the expectations on each mock method in the 69413481Sgiacomo.travaglini@arm.com // given mock object. 69513481Sgiacomo.travaglini@arm.com bool expectations_met = true; 69613481Sgiacomo.travaglini@arm.com FunctionMockers& mockers = 69713481Sgiacomo.travaglini@arm.com g_mock_object_registry.states()[mock_obj].function_mockers; 69813481Sgiacomo.travaglini@arm.com for (FunctionMockers::const_iterator it = mockers.begin(); 69913481Sgiacomo.travaglini@arm.com it != mockers.end(); ++it) { 70013481Sgiacomo.travaglini@arm.com if (!(*it)->VerifyAndClearExpectationsLocked()) { 70113481Sgiacomo.travaglini@arm.com expectations_met = false; 70213481Sgiacomo.travaglini@arm.com } 70313481Sgiacomo.travaglini@arm.com } 70413481Sgiacomo.travaglini@arm.com 70513481Sgiacomo.travaglini@arm.com // We don't clear the content of mockers, as they may still be 70613481Sgiacomo.travaglini@arm.com // needed by ClearDefaultActionsLocked(). 70713481Sgiacomo.travaglini@arm.com return expectations_met; 70813481Sgiacomo.travaglini@arm.com} 70913481Sgiacomo.travaglini@arm.com 71013481Sgiacomo.travaglini@arm.com// Registers a mock object and a mock method it owns. 71113481Sgiacomo.travaglini@arm.comvoid Mock::Register(const void* mock_obj, 71213481Sgiacomo.travaglini@arm.com internal::UntypedFunctionMockerBase* mocker) 71313481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 71413481Sgiacomo.travaglini@arm.com internal::MutexLock l(&internal::g_gmock_mutex); 71513481Sgiacomo.travaglini@arm.com g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker); 71613481Sgiacomo.travaglini@arm.com} 71713481Sgiacomo.travaglini@arm.com 71813481Sgiacomo.travaglini@arm.com// Tells Google Mock where in the source code mock_obj is used in an 71913481Sgiacomo.travaglini@arm.com// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this 72013481Sgiacomo.travaglini@arm.com// information helps the user identify which object it is. 72113481Sgiacomo.travaglini@arm.comvoid Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj, 72213481Sgiacomo.travaglini@arm.com const char* file, int line) 72313481Sgiacomo.travaglini@arm.com GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 72413481Sgiacomo.travaglini@arm.com internal::MutexLock l(&internal::g_gmock_mutex); 72513481Sgiacomo.travaglini@arm.com MockObjectState& state = g_mock_object_registry.states()[mock_obj]; 72613481Sgiacomo.travaglini@arm.com if (state.first_used_file == NULL) { 72713481Sgiacomo.travaglini@arm.com state.first_used_file = file; 72813481Sgiacomo.travaglini@arm.com state.first_used_line = line; 72913481Sgiacomo.travaglini@arm.com const TestInfo* const test_info = 73013481Sgiacomo.travaglini@arm.com UnitTest::GetInstance()->current_test_info(); 73113481Sgiacomo.travaglini@arm.com if (test_info != NULL) { 73213481Sgiacomo.travaglini@arm.com // TODO(wan@google.com): record the test case name when the 73313481Sgiacomo.travaglini@arm.com // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or 73413481Sgiacomo.travaglini@arm.com // TearDownTestCase(). 73513481Sgiacomo.travaglini@arm.com state.first_used_test_case = test_info->test_case_name(); 73613481Sgiacomo.travaglini@arm.com state.first_used_test = test_info->name(); 73713481Sgiacomo.travaglini@arm.com } 73813481Sgiacomo.travaglini@arm.com } 73913481Sgiacomo.travaglini@arm.com} 74013481Sgiacomo.travaglini@arm.com 74113481Sgiacomo.travaglini@arm.com// Unregisters a mock method; removes the owning mock object from the 74213481Sgiacomo.travaglini@arm.com// registry when the last mock method associated with it has been 74313481Sgiacomo.travaglini@arm.com// unregistered. This is called only in the destructor of 74413481Sgiacomo.travaglini@arm.com// FunctionMockerBase. 74513481Sgiacomo.travaglini@arm.comvoid Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) 74613481Sgiacomo.travaglini@arm.com GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { 74713481Sgiacomo.travaglini@arm.com internal::g_gmock_mutex.AssertHeld(); 74813481Sgiacomo.travaglini@arm.com for (MockObjectRegistry::StateMap::iterator it = 74913481Sgiacomo.travaglini@arm.com g_mock_object_registry.states().begin(); 75013481Sgiacomo.travaglini@arm.com it != g_mock_object_registry.states().end(); ++it) { 75113481Sgiacomo.travaglini@arm.com FunctionMockers& mockers = it->second.function_mockers; 75213481Sgiacomo.travaglini@arm.com if (mockers.erase(mocker) > 0) { 75313481Sgiacomo.travaglini@arm.com // mocker was in mockers and has been just removed. 75413481Sgiacomo.travaglini@arm.com if (mockers.empty()) { 75513481Sgiacomo.travaglini@arm.com g_mock_object_registry.states().erase(it); 75613481Sgiacomo.travaglini@arm.com } 75713481Sgiacomo.travaglini@arm.com return; 75813481Sgiacomo.travaglini@arm.com } 75913481Sgiacomo.travaglini@arm.com } 76013481Sgiacomo.travaglini@arm.com} 76113481Sgiacomo.travaglini@arm.com 76213481Sgiacomo.travaglini@arm.com// Clears all ON_CALL()s set on the given mock object. 76313481Sgiacomo.travaglini@arm.comvoid Mock::ClearDefaultActionsLocked(void* mock_obj) 76413481Sgiacomo.travaglini@arm.com GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { 76513481Sgiacomo.travaglini@arm.com internal::g_gmock_mutex.AssertHeld(); 76613481Sgiacomo.travaglini@arm.com 76713481Sgiacomo.travaglini@arm.com if (g_mock_object_registry.states().count(mock_obj) == 0) { 76813481Sgiacomo.travaglini@arm.com // No ON_CALL() was set on the given mock object. 76913481Sgiacomo.travaglini@arm.com return; 77013481Sgiacomo.travaglini@arm.com } 77113481Sgiacomo.travaglini@arm.com 77213481Sgiacomo.travaglini@arm.com // Clears the default actions for each mock method in the given mock 77313481Sgiacomo.travaglini@arm.com // object. 77413481Sgiacomo.travaglini@arm.com FunctionMockers& mockers = 77513481Sgiacomo.travaglini@arm.com g_mock_object_registry.states()[mock_obj].function_mockers; 77613481Sgiacomo.travaglini@arm.com for (FunctionMockers::const_iterator it = mockers.begin(); 77713481Sgiacomo.travaglini@arm.com it != mockers.end(); ++it) { 77813481Sgiacomo.travaglini@arm.com (*it)->ClearDefaultActionsLocked(); 77913481Sgiacomo.travaglini@arm.com } 78013481Sgiacomo.travaglini@arm.com 78113481Sgiacomo.travaglini@arm.com // We don't clear the content of mockers, as they may still be 78213481Sgiacomo.travaglini@arm.com // needed by VerifyAndClearExpectationsLocked(). 78313481Sgiacomo.travaglini@arm.com} 78413481Sgiacomo.travaglini@arm.com 78513481Sgiacomo.travaglini@arm.comExpectation::Expectation() {} 78613481Sgiacomo.travaglini@arm.com 78713481Sgiacomo.travaglini@arm.comExpectation::Expectation( 78813481Sgiacomo.travaglini@arm.com const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base) 78913481Sgiacomo.travaglini@arm.com : expectation_base_(an_expectation_base) {} 79013481Sgiacomo.travaglini@arm.com 79113481Sgiacomo.travaglini@arm.comExpectation::~Expectation() {} 79213481Sgiacomo.travaglini@arm.com 79313481Sgiacomo.travaglini@arm.com// Adds an expectation to a sequence. 79413481Sgiacomo.travaglini@arm.comvoid Sequence::AddExpectation(const Expectation& expectation) const { 79513481Sgiacomo.travaglini@arm.com if (*last_expectation_ != expectation) { 79613481Sgiacomo.travaglini@arm.com if (last_expectation_->expectation_base() != NULL) { 79713481Sgiacomo.travaglini@arm.com expectation.expectation_base()->immediate_prerequisites_ 79813481Sgiacomo.travaglini@arm.com += *last_expectation_; 79913481Sgiacomo.travaglini@arm.com } 80013481Sgiacomo.travaglini@arm.com *last_expectation_ = expectation; 80113481Sgiacomo.travaglini@arm.com } 80213481Sgiacomo.travaglini@arm.com} 80313481Sgiacomo.travaglini@arm.com 80413481Sgiacomo.travaglini@arm.com// Creates the implicit sequence if there isn't one. 80513481Sgiacomo.travaglini@arm.comInSequence::InSequence() { 80613481Sgiacomo.travaglini@arm.com if (internal::g_gmock_implicit_sequence.get() == NULL) { 80713481Sgiacomo.travaglini@arm.com internal::g_gmock_implicit_sequence.set(new Sequence); 80813481Sgiacomo.travaglini@arm.com sequence_created_ = true; 80913481Sgiacomo.travaglini@arm.com } else { 81013481Sgiacomo.travaglini@arm.com sequence_created_ = false; 81113481Sgiacomo.travaglini@arm.com } 81213481Sgiacomo.travaglini@arm.com} 81313481Sgiacomo.travaglini@arm.com 81413481Sgiacomo.travaglini@arm.com// Deletes the implicit sequence if it was created by the constructor 81513481Sgiacomo.travaglini@arm.com// of this object. 81613481Sgiacomo.travaglini@arm.comInSequence::~InSequence() { 81713481Sgiacomo.travaglini@arm.com if (sequence_created_) { 81813481Sgiacomo.travaglini@arm.com delete internal::g_gmock_implicit_sequence.get(); 81913481Sgiacomo.travaglini@arm.com internal::g_gmock_implicit_sequence.set(NULL); 82013481Sgiacomo.travaglini@arm.com } 82113481Sgiacomo.travaglini@arm.com} 82213481Sgiacomo.travaglini@arm.com 82313481Sgiacomo.travaglini@arm.com} // namespace testing 824