gmock-spec-builders.cc (googletest-release-1.11.0) | : | gmock-spec-builders.cc (googletest-release-1.12.0) | ||
---|---|---|---|---|
skipping to change at line 44 | skipping to change at line 44 | |||
#include "gmock/gmock-spec-builders.h" | #include "gmock/gmock-spec-builders.h" | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <iostream> // NOLINT | #include <iostream> // NOLINT | |||
#include <map> | #include <map> | |||
#include <memory> | #include <memory> | |||
#include <set> | #include <set> | |||
#include <string> | #include <string> | |||
#include <unordered_map> | ||||
#include <vector> | #include <vector> | |||
#include "gmock/gmock.h" | #include "gmock/gmock.h" | |||
#include "gtest/gtest.h" | #include "gtest/gtest.h" | |||
#include "gtest/internal/gtest-port.h" | #include "gtest/internal/gtest-port.h" | |||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC | #if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC | |||
# include <unistd.h> // NOLINT | #include <unistd.h> // NOLINT | |||
#endif | #endif | |||
// Silence C4800 (C4800: 'int *const ': forcing value | // Silence C4800 (C4800: 'int *const ': forcing value | |||
// to bool 'true' or 'false') for MSVC 15 | // to bool 'true' or 'false') for MSVC 15 | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#if _MSC_VER == 1900 | #if _MSC_VER == 1900 | |||
# pragma warning(push) | #pragma warning(push) | |||
# pragma warning(disable:4800) | #pragma warning(disable : 4800) | |||
#endif | #endif | |||
#endif | #endif | |||
namespace testing { | namespace testing { | |||
namespace internal { | namespace internal { | |||
// Protects the mock object registry (in class Mock), all function | // Protects the mock object registry (in class Mock), all function | |||
// mockers, and all expectations. | // mockers, and all expectations. | |||
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); | GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); | |||
skipping to change at line 197 | skipping to change at line 198 | |||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
// Describes how many times the function is expected to be called. | // Describes how many times the function is expected to be called. | |||
*os << " Expected: to be "; | *os << " Expected: to be "; | |||
cardinality().DescribeTo(os); | cardinality().DescribeTo(os); | |||
*os << "\n Actual: "; | *os << "\n Actual: "; | |||
Cardinality::DescribeActualCallCountTo(call_count(), os); | Cardinality::DescribeActualCallCountTo(call_count(), os); | |||
// Describes the state of the expectation (e.g. is it satisfied? | // Describes the state of the expectation (e.g. is it satisfied? | |||
// is it active?). | // is it active?). | |||
*os << " - " << (IsOverSaturated() ? "over-saturated" : | *os << " - " | |||
IsSaturated() ? "saturated" : | << (IsOverSaturated() ? "over-saturated" | |||
IsSatisfied() ? "satisfied" : "unsatisfied") | : IsSaturated() ? "saturated" | |||
<< " and " | : IsSatisfied() ? "satisfied" | |||
<< (is_retired() ? "retired" : "active"); | : "unsatisfied") | |||
<< " and " << (is_retired() ? "retired" : "active"); | ||||
} | } | |||
// 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 ExpectationBase::CheckActionCountIfNotDone() const | void ExpectationBase::CheckActionCountIfNotDone() const | |||
GTEST_LOCK_EXCLUDED_(mutex_) { | GTEST_LOCK_EXCLUDED_(mutex_) { | |||
bool should_check = false; | bool should_check = false; | |||
{ | { | |||
skipping to change at line 244 | skipping to change at line 246 | |||
too_many = true; | too_many = true; | |||
} else if (0 < action_count && action_count < lower_bound && | } else if (0 < action_count && action_count < lower_bound && | |||
!repeated_action_specified_) { | !repeated_action_specified_) { | |||
too_many = false; | too_many = false; | |||
} else { | } else { | |||
return; | return; | |||
} | } | |||
::std::stringstream ss; | ::std::stringstream ss; | |||
DescribeLocationTo(&ss); | DescribeLocationTo(&ss); | |||
ss << "Too " << (too_many ? "many" : "few") | ss << "Too " << (too_many ? "many" : "few") << " actions specified in " | |||
<< " actions specified in " << source_text() << "...\n" | << source_text() << "...\n" | |||
<< "Expected to be "; | << "Expected to be "; | |||
cardinality().DescribeTo(&ss); | cardinality().DescribeTo(&ss); | |||
ss << ", but has " << (too_many ? "" : "only ") | ss << ", but has " << (too_many ? "" : "only ") << action_count | |||
<< action_count << " WillOnce()" | << " WillOnce()" << (action_count == 1 ? "" : "s"); | |||
<< (action_count == 1 ? "" : "s"); | ||||
if (repeated_action_specified_) { | if (repeated_action_specified_) { | |||
ss << " and a WillRepeatedly()"; | ss << " and a WillRepeatedly()"; | |||
} | } | |||
ss << "."; | ss << "."; | |||
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace". | Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace". | |||
} | } | |||
} | } | |||
// Implements the .Times() clause. | // Implements the .Times() clause. | |||
void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { | void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { | |||
if (last_clause_ == kTimes) { | if (last_clause_ == kTimes) { | |||
ExpectSpecProperty(false, | ExpectSpecProperty(false, | |||
".Times() cannot appear " | ".Times() cannot appear " | |||
"more than once in an EXPECT_CALL()."); | "more than once in an EXPECT_CALL()."); | |||
} else { | } else { | |||
ExpectSpecProperty(last_clause_ < kTimes, | ExpectSpecProperty( | |||
".Times() cannot appear after " | last_clause_ < kTimes, | |||
".InSequence(), .WillOnce(), .WillRepeatedly(), " | ".Times() may only appear *before* .InSequence(), .WillOnce(), " | |||
"or .RetiresOnSaturation()."); | ".WillRepeatedly(), or .RetiresOnSaturation(), not after."); | |||
} | } | |||
last_clause_ = kTimes; | last_clause_ = kTimes; | |||
SpecifyCardinality(a_cardinality); | SpecifyCardinality(a_cardinality); | |||
} | } | |||
// 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_ ThreadLocal<Sequence*> g_gmock_implicit_sequence; | GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence; | |||
// Reports an uninteresting call (whose description is in msg) in the | // Reports an uninteresting call (whose description is in msg) in the | |||
// manner specified by 'reaction'. | // manner specified by 'reaction'. | |||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) { | void ReportUninterestingCall(CallReaction reaction, const std::string& msg) { | |||
// Include a stack trace only if --gmock_verbose=info is specified. | // Include a stack trace only if --gmock_verbose=info is specified. | |||
const int stack_frames_to_skip = | const int stack_frames_to_skip = | |||
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1; | GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1; | |||
switch (reaction) { | switch (reaction) { | |||
case kAllow: | case kAllow: | |||
Log(kInfo, msg, stack_frames_to_skip); | Log(kInfo, msg, stack_frames_to_skip); | |||
break; | break; | |||
case kWarn: | case kWarn: | |||
Log(kWarning, | Log(kWarning, | |||
msg + | msg + | |||
"\nNOTE: You can safely ignore the above warning unless this " | "\nNOTE: You can safely ignore the above warning unless this " | |||
"call should not happen. Do not suppress it by blindly adding " | "call should not happen. Do not suppress it by blindly adding " | |||
"an EXPECT_CALL() if you don't mean to enforce the call. " | "an EXPECT_CALL() if you don't mean to enforce the call. " | |||
skipping to change at line 372 | skipping to change at line 373 | |||
// function is called from two threads concurrently. | // function is called from two threads concurrently. | |||
MutexLock l(&g_gmock_mutex); | MutexLock l(&g_gmock_mutex); | |||
Assert(name_ != nullptr, __FILE__, __LINE__, | Assert(name_ != nullptr, __FILE__, __LINE__, | |||
"Name() must not be called before SetOwnerAndName() has " | "Name() must not be called before SetOwnerAndName() has " | |||
"been called."); | "been called."); | |||
name = name_; | name = name_; | |||
} | } | |||
return name; | return name; | |||
} | } | |||
// Calculates the result of invoking this mock function with the given | ||||
// arguments, prints it, and returns it. The caller is responsible | ||||
// for deleting the result. | ||||
UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith( | ||||
void* const untyped_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->UntypedPerformDefaultAction( | ||||
untyped_args, "Function call: " + std::string(Name())); | ||||
} | ||||
// Warns about the uninteresting call. | ||||
::std::stringstream ss; | ||||
this->UntypedDescribeUninterestingCall(untyped_args, &ss); | ||||
// Calculates the function result. | ||||
UntypedActionResultHolderBase* const result = | ||||
this->UntypedPerformDefaultAction(untyped_args, ss.str()); | ||||
// Prints the function result. | ||||
if (result != nullptr) result->PrintAsActionResult(&ss); | ||||
ReportUninterestingCall(reaction, ss.str()); | ||||
return result; | ||||
} | ||||
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(untyped_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 untyped_action == nullptr | ||||
? this->UntypedPerformDefaultAction(untyped_args, "") | ||||
: this->UntypedPerformAction(untyped_action, untyped_args); | ||||
} | ||||
ss << " Function call: " << Name(); | ||||
this->UntypedPrintArgs(untyped_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); | ||||
} | ||||
UntypedActionResultHolderBase* result = nullptr; | ||||
auto perform_action = [&] { | ||||
return untyped_action == nullptr | ||||
? this->UntypedPerformDefaultAction(untyped_args, ss.str()) | ||||
: this->UntypedPerformAction(untyped_action, untyped_args); | ||||
}; | ||||
auto 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); | ||||
} | ||||
}; | ||||
#if GTEST_HAS_EXCEPTIONS | ||||
try { | ||||
result = perform_action(); | ||||
} catch (...) { | ||||
handle_failures(); | ||||
throw; | ||||
} | ||||
#else | ||||
result = perform_action(); | ||||
#endif | ||||
if (result != nullptr) result->PrintAsActionResult(&ss); | ||||
handle_failures(); | ||||
return result; | ||||
} | ||||
// 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 UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { | Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { | |||
// See the definition of untyped_expectations_ for why access to it | // See the definition of untyped_expectations_ for why access to it | |||
// is unprotected here. | // is unprotected here. | |||
for (UntypedExpectations::const_iterator it = | for (UntypedExpectations::const_iterator it = untyped_expectations_.begin(); | |||
untyped_expectations_.begin(); | ||||
it != untyped_expectations_.end(); ++it) { | it != untyped_expectations_.end(); ++it) { | |||
if (it->get() == exp) { | if (it->get() == exp) { | |||
return Expectation(*it); | return Expectation(*it); | |||
} | } | |||
} | } | |||
Assert(false, __FILE__, __LINE__, "Cannot find expectation."); | Assert(false, __FILE__, __LINE__, "Cannot find expectation."); | |||
return Expectation(); | return Expectation(); | |||
// The above statement is just to make the code compile, and will | // The above statement is just to make the code compile, and will | |||
// never be executed. | // never be executed. | |||
} | } | |||
// 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 | |||
// and returns false if not. | // and returns false if not. | |||
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() | bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() | |||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { | |||
g_gmock_mutex.AssertHeld(); | g_gmock_mutex.AssertHeld(); | |||
bool expectations_met = true; | bool expectations_met = true; | |||
for (UntypedExpectations::const_iterator it = | for (UntypedExpectations::const_iterator it = untyped_expectations_.begin(); | |||
untyped_expectations_.begin(); | ||||
it != untyped_expectations_.end(); ++it) { | it != untyped_expectations_.end(); ++it) { | |||
ExpectationBase* const untyped_expectation = it->get(); | ExpectationBase* const untyped_expectation = it->get(); | |||
if (untyped_expectation->IsOverSaturated()) { | if (untyped_expectation->IsOverSaturated()) { | |||
// There was an upper-bound violation. Since the error was | // There was an upper-bound violation. Since the error was | |||
// already reported when it occurred, there is no need to do | // already reported when it occurred, there is no need to do | |||
// anything here. | // anything here. | |||
expectations_met = false; | expectations_met = false; | |||
} else if (!untyped_expectation->IsSatisfied()) { | } else if (!untyped_expectation->IsSatisfied()) { | |||
expectations_met = false; | expectations_met = false; | |||
::std::stringstream ss; | ::std::stringstream ss; | |||
ss << "Actual function call count doesn't match " | ss << "Actual function call count doesn't match " | |||
<< untyped_expectation->source_text() << "...\n"; | << untyped_expectation->source_text() << "...\n"; | |||
// No need to show the source file location of the expectation | // No need to show the source file location of the expectation | |||
// in the description, as the Expect() call that follows already | // in the description, as the Expect() call that follows already | |||
// takes care of it. | // takes care of it. | |||
untyped_expectation->MaybeDescribeExtraMatcherTo(&ss); | untyped_expectation->MaybeDescribeExtraMatcherTo(&ss); | |||
untyped_expectation->DescribeCallCountTo(&ss); | untyped_expectation->DescribeCallCountTo(&ss); | |||
Expect(false, untyped_expectation->file(), | Expect(false, untyped_expectation->file(), untyped_expectation->line(), | |||
untyped_expectation->line(), ss.str()); | ss.str()); | |||
} | } | |||
} | } | |||
// Deleting our expectations may trigger other mock objects to be deleted, for | // Deleting our expectations may trigger other mock objects to be deleted, for | |||
// example if an action contains a reference counted smart pointer to that | // example if an action contains a reference counted smart pointer to that | |||
// mock object, and that is the last reference. So if we delete our | // mock object, and that is the last reference. So if we delete our | |||
// expectations within the context of the global mutex we may deadlock when | // expectations within the context of the global mutex we may deadlock when | |||
// this method is called again. Instead, make a copy of the set of | // this method is called again. Instead, make a copy of the set of | |||
// expectations to delete, clear our set within the mutex, and then clear the | // expectations to delete, clear our set within the mutex, and then clear the | |||
// copied set outside of it. | // copied set outside of it. | |||
skipping to change at line 615 | skipping to change at line 484 | |||
class MockObjectRegistry { | class MockObjectRegistry { | |||
public: | public: | |||
// Maps a mock object (identified by its address) to its state. | // Maps a mock object (identified by its address) to its state. | |||
typedef std::map<const void*, MockObjectState> StateMap; | typedef std::map<const void*, MockObjectState> StateMap; | |||
// This destructor will be called when a program exits, after all | // This destructor will be called when a program exits, after all | |||
// tests in it have been run. By then, there should be no mock | // tests in it have been run. By then, there should be no mock | |||
// object alive. Therefore we report any living object as test | // object alive. Therefore we report any living object as test | |||
// failure, unless the user explicitly asked us to ignore it. | // failure, unless the user explicitly asked us to ignore it. | |||
~MockObjectRegistry() { | ~MockObjectRegistry() { | |||
if (!GMOCK_FLAG(catch_leaked_mocks)) | if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return; | |||
return; | ||||
int leaked_count = 0; | int leaked_count = 0; | |||
for (StateMap::const_iterator it = states_.begin(); it != states_.end(); | for (StateMap::const_iterator it = states_.begin(); it != states_.end(); | |||
++it) { | ++it) { | |||
if (it->second.leakable) // The user said it's fine to leak this object. | if (it->second.leakable) // The user said it's fine to leak this object. | |||
continue; | continue; | |||
// FIXME: Print the type of the leaked object. | // FIXME: Print the type of the leaked object. | |||
// This can help the user identify the leaked object. | // This can help the user identify the leaked object. | |||
std::cout << "\n"; | std::cout << "\n"; | |||
const MockObjectState& state = it->second; | const MockObjectState& state = it->second; | |||
std::cout << internal::FormatFileLocation(state.first_used_file, | std::cout << internal::FormatFileLocation(state.first_used_file, | |||
state.first_used_line); | state.first_used_line); | |||
std::cout << " ERROR: this mock object"; | std::cout << " ERROR: this mock object"; | |||
if (state.first_used_test != "") { | if (state.first_used_test != "") { | |||
std::cout << " (used in test " << state.first_used_test_suite << "." | std::cout << " (used in test " << state.first_used_test_suite << "." | |||
<< state.first_used_test << ")"; | << state.first_used_test << ")"; | |||
} | } | |||
std::cout << " should be deleted but never is. Its address is @" | std::cout << " should be deleted but never is. Its address is @" | |||
<< it->first << "."; | << it->first << "."; | |||
leaked_count++; | leaked_count++; | |||
} | } | |||
if (leaked_count > 0) { | if (leaked_count > 0) { | |||
std::cout << "\nERROR: " << leaked_count << " leaked mock " | std::cout << "\nERROR: " << leaked_count << " leaked mock " | |||
<< (leaked_count == 1 ? "object" : "objects") | << (leaked_count == 1 ? "object" : "objects") | |||
<< " found at program exit. Expectations on a mock object are " | << " found at program exit. Expectations on a mock object are " | |||
"verified when the object is destructed. Leaking a mock " | "verified when the object is destructed. Leaking a mock " | |||
"means that its expectations aren't verified, which is " | "means that its expectations aren't verified, which is " | |||
"usually a test bug. If you really intend to leak a mock, " | "usually a test bug. If you really intend to leak a mock, " | |||
"you can suppress this error using " | "you can suppress this error using " | |||
skipping to change at line 670 | skipping to change at line 538 | |||
private: | private: | |||
StateMap states_; | StateMap states_; | |||
}; | }; | |||
// Protected by g_gmock_mutex. | // Protected by g_gmock_mutex. | |||
MockObjectRegistry g_mock_object_registry; | MockObjectRegistry g_mock_object_registry; | |||
// Maps a mock object to the reaction Google Mock should have when an | // Maps a mock object to the reaction Google Mock should have when an | |||
// uninteresting method is called. Protected by g_gmock_mutex. | // uninteresting method is called. Protected by g_gmock_mutex. | |||
std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction; | std::unordered_map<uintptr_t, internal::CallReaction>& | |||
UninterestingCallReactionMap() { | ||||
static auto* map = new std::unordered_map<uintptr_t, internal::CallReaction>; | ||||
return *map; | ||||
} | ||||
// Sets the reaction Google Mock should have when an uninteresting | // Sets the reaction Google Mock should have when an uninteresting | |||
// method of the given mock object is called. | // method of the given mock object is called. | |||
void SetReactionOnUninterestingCalls(const void* mock_obj, | void SetReactionOnUninterestingCalls(uintptr_t mock_obj, | |||
internal::CallReaction reaction) | internal::CallReaction reaction) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | |||
internal::MutexLock l(&internal::g_gmock_mutex); | internal::MutexLock l(&internal::g_gmock_mutex); | |||
g_uninteresting_call_reaction[mock_obj] = reaction; | UninterestingCallReactionMap()[mock_obj] = reaction; | |||
} | } | |||
} // namespace | } // namespace | |||
// Tells Google Mock to allow uninteresting calls on the given mock | // Tells Google Mock to allow uninteresting calls on the given mock | |||
// object. | // object. | |||
void Mock::AllowUninterestingCalls(const void* mock_obj) | void Mock::AllowUninterestingCalls(uintptr_t mock_obj) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | |||
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow); | SetReactionOnUninterestingCalls(mock_obj, internal::kAllow); | |||
} | } | |||
// Tells Google Mock to warn the user about uninteresting calls on the | // Tells Google Mock to warn the user about uninteresting calls on the | |||
// given mock object. | // given mock object. | |||
void Mock::WarnUninterestingCalls(const void* mock_obj) | void Mock::WarnUninterestingCalls(uintptr_t mock_obj) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | |||
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn); | SetReactionOnUninterestingCalls(mock_obj, internal::kWarn); | |||
} | } | |||
// Tells Google Mock to fail uninteresting calls on the given mock | // Tells Google Mock to fail uninteresting calls on the given mock | |||
// object. | // object. | |||
void Mock::FailUninterestingCalls(const void* mock_obj) | void Mock::FailUninterestingCalls(uintptr_t mock_obj) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | |||
SetReactionOnUninterestingCalls(mock_obj, internal::kFail); | SetReactionOnUninterestingCalls(mock_obj, internal::kFail); | |||
} | } | |||
// Tells Google Mock the given mock object is being destroyed and its | // Tells Google Mock the given mock object is being destroyed and its | |||
// entry in the call-reaction table should be removed. | // entry in the call-reaction table should be removed. | |||
void Mock::UnregisterCallReaction(const void* mock_obj) | void Mock::UnregisterCallReaction(uintptr_t mock_obj) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | |||
internal::MutexLock l(&internal::g_gmock_mutex); | internal::MutexLock l(&internal::g_gmock_mutex); | |||
g_uninteresting_call_reaction.erase(mock_obj); | UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj)); | |||
} | } | |||
// 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. | |||
internal::CallReaction Mock::GetReactionOnUninterestingCalls( | internal::CallReaction Mock::GetReactionOnUninterestingCalls( | |||
const void* mock_obj) | const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | ||||
internal::MutexLock l(&internal::g_gmock_mutex); | internal::MutexLock l(&internal::g_gmock_mutex); | |||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ? | return (UninterestingCallReactionMap().count( | |||
internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) : | reinterpret_cast<uintptr_t>(mock_obj)) == 0) | |||
g_uninteresting_call_reaction[mock_obj]; | ? internal::intToCallReaction( | |||
GMOCK_FLAG_GET(default_mock_behavior)) | ||||
: UninterestingCallReactionMap()[reinterpret_cast<uintptr_t>( | ||||
mock_obj)]; | ||||
} | } | |||
// Tells Google Mock to ignore mock_obj when checking for leaked mock | // Tells Google Mock to ignore mock_obj when checking for leaked mock | |||
// objects. | // objects. | |||
void Mock::AllowLeak(const void* mock_obj) | void Mock::AllowLeak(const void* mock_obj) | |||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { | |||
internal::MutexLock l(&internal::g_gmock_mutex); | internal::MutexLock l(&internal::g_gmock_mutex); | |||
g_mock_object_registry.states()[mock_obj].leakable = true; | g_mock_object_registry.states()[mock_obj].leakable = true; | |||
} | } | |||
skipping to change at line 875 | skipping to change at line 749 | |||
Expectation::Expectation( | Expectation::Expectation( | |||
const std::shared_ptr<internal::ExpectationBase>& an_expectation_base) | const std::shared_ptr<internal::ExpectationBase>& an_expectation_base) | |||
: expectation_base_(an_expectation_base) {} | : expectation_base_(an_expectation_base) {} | |||
Expectation::~Expectation() {} | Expectation::~Expectation() {} | |||
// Adds an expectation to a sequence. | // Adds an expectation to a sequence. | |||
void Sequence::AddExpectation(const Expectation& expectation) const { | void Sequence::AddExpectation(const Expectation& expectation) const { | |||
if (*last_expectation_ != expectation) { | if (*last_expectation_ != expectation) { | |||
if (last_expectation_->expectation_base() != nullptr) { | if (last_expectation_->expectation_base() != nullptr) { | |||
expectation.expectation_base()->immediate_prerequisites_ | expectation.expectation_base()->immediate_prerequisites_ += | |||
+= *last_expectation_; | *last_expectation_; | |||
} | } | |||
*last_expectation_ = expectation; | *last_expectation_ = expectation; | |||
} | } | |||
} | } | |||
// Creates the implicit sequence if there isn't one. | // Creates the implicit sequence if there isn't one. | |||
InSequence::InSequence() { | InSequence::InSequence() { | |||
if (internal::g_gmock_implicit_sequence.get() == nullptr) { | if (internal::g_gmock_implicit_sequence.get() == nullptr) { | |||
internal::g_gmock_implicit_sequence.set(new Sequence); | internal::g_gmock_implicit_sequence.set(new Sequence); | |||
sequence_created_ = true; | sequence_created_ = true; | |||
skipping to change at line 905 | skipping to change at line 779 | |||
if (sequence_created_) { | if (sequence_created_) { | |||
delete internal::g_gmock_implicit_sequence.get(); | delete internal::g_gmock_implicit_sequence.get(); | |||
internal::g_gmock_implicit_sequence.set(nullptr); | internal::g_gmock_implicit_sequence.set(nullptr); | |||
} | } | |||
} | } | |||
} // namespace testing | } // namespace testing | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#if _MSC_VER == 1900 | #if _MSC_VER == 1900 | |||
# pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#endif | #endif | |||
End of changes. 27 change blocks. | ||||
175 lines changed or deleted | 49 lines changed or added |