35#include "gmock/gmock-spec-builders.h"
44#include <unordered_map>
47#include "gmock/gmock.h"
48#include "gtest/gtest.h"
49#include "gtest/internal/gtest-port.h"
51#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
55#include <qurt_event.h>
63#pragma warning(disable : 4800)
72GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
75GTEST_API_
void LogWithLocation(testing::internal::LogSeverity severity,
76 const char* file,
int line,
77 const std::string& message) {
78 ::std::ostringstream s;
79 s << internal::FormatFileLocation(file, line) <<
" " << message
81 Log(severity, s.str(), 0);
85ExpectationBase::ExpectationBase(
const char* a_file,
int a_line,
86 const std::string& a_source_text)
89 source_text_(a_source_text),
90 cardinality_specified_(false),
91 cardinality_(Exactly(1)),
94 extra_matcher_specified_(false),
95 repeated_action_specified_(false),
96 retires_on_saturation_(false),
98 action_count_checked_(false) {}
101ExpectationBase::~ExpectationBase() {}
105void ExpectationBase::SpecifyCardinality(
const Cardinality& a_cardinality) {
106 cardinality_specified_ =
true;
107 cardinality_ = a_cardinality;
111void ExpectationBase::RetireAllPreRequisites()
112 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
119 ::std::vector<ExpectationBase*> expectations(1,
this);
120 while (!expectations.empty()) {
121 ExpectationBase* exp = expectations.back();
122 expectations.pop_back();
124 for (ExpectationSet::const_iterator it =
125 exp->immediate_prerequisites_.begin();
126 it != exp->immediate_prerequisites_.end(); ++it) {
127 ExpectationBase* next = it->expectation_base().get();
128 if (!next->is_retired()) {
130 expectations.push_back(next);
138bool ExpectationBase::AllPrerequisitesAreSatisfied() const
139 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
140 g_gmock_mutex.AssertHeld();
141 ::std::vector<const ExpectationBase*> expectations(1,
this);
142 while (!expectations.empty()) {
143 const ExpectationBase* exp = expectations.back();
144 expectations.pop_back();
146 for (ExpectationSet::const_iterator it =
147 exp->immediate_prerequisites_.begin();
148 it != exp->immediate_prerequisites_.end(); ++it) {
149 const ExpectationBase* next = it->expectation_base().get();
150 if (!next->IsSatisfied())
return false;
151 expectations.push_back(next);
158void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result)
const
159 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
160 g_gmock_mutex.AssertHeld();
161 ::std::vector<const ExpectationBase*> expectations(1,
this);
162 while (!expectations.empty()) {
163 const ExpectationBase* exp = expectations.back();
164 expectations.pop_back();
166 for (ExpectationSet::const_iterator it =
167 exp->immediate_prerequisites_.begin();
168 it != exp->immediate_prerequisites_.end(); ++it) {
169 const ExpectationBase* next = it->expectation_base().get();
171 if (next->IsSatisfied()) {
174 if (next->call_count_ == 0) {
175 expectations.push_back(next);
189void ExpectationBase::DescribeCallCountTo(::std::ostream* os)
const
190 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
191 g_gmock_mutex.AssertHeld();
194 *os <<
" Expected: to be ";
195 cardinality().DescribeTo(os);
196 *os <<
"\n Actual: ";
197 Cardinality::DescribeActualCallCountTo(call_count(), os);
202 << (IsOverSaturated() ?
"over-saturated"
203 : IsSaturated() ?
"saturated"
204 : IsSatisfied() ?
"satisfied"
206 <<
" and " << (is_retired() ?
"retired" :
"active");
213void ExpectationBase::CheckActionCountIfNotDone() const
214 GTEST_LOCK_EXCLUDED_(mutex_) {
215 bool should_check =
false;
217 MutexLock l(&mutex_);
218 if (!action_count_checked_) {
219 action_count_checked_ =
true;
225 if (!cardinality_specified_) {
232 const int action_count =
static_cast<int>(untyped_actions_.size());
233 const int upper_bound = cardinality().ConservativeUpperBound();
234 const int lower_bound = cardinality().ConservativeLowerBound();
237 if (action_count > upper_bound ||
238 (action_count == upper_bound && repeated_action_specified_)) {
240 }
else if (0 < action_count && action_count < lower_bound &&
241 !repeated_action_specified_) {
247 ::std::stringstream ss;
248 DescribeLocationTo(&ss);
249 ss <<
"Too " << (too_many ?
"many" :
"few") <<
" actions specified in "
250 << source_text() <<
"...\n"
251 <<
"Expected to be ";
252 cardinality().DescribeTo(&ss);
253 ss <<
", but has " << (too_many ?
"" :
"only ") << action_count
254 <<
" WillOnce()" << (action_count == 1 ?
"" :
"s");
255 if (repeated_action_specified_) {
256 ss <<
" and a WillRepeatedly()";
259 Log(kWarning, ss.str(), -1);
264void ExpectationBase::UntypedTimes(
const Cardinality& a_cardinality) {
265 if (last_clause_ == kTimes) {
266 ExpectSpecProperty(
false,
267 ".Times() cannot appear "
268 "more than once in an EXPECT_CALL().");
271 last_clause_ < kTimes,
272 ".Times() may only appear *before* .InSequence(), .WillOnce(), "
273 ".WillRepeatedly(), or .RetiresOnSaturation(), not after.");
275 last_clause_ = kTimes;
277 SpecifyCardinality(a_cardinality);
282GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
286void ReportUninterestingCall(CallReaction reaction,
const std::string& msg) {
288 const int stack_frames_to_skip =
289 GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1;
292 Log(kInfo, msg, stack_frames_to_skip);
297 "\nNOTE: You can safely ignore the above warning unless this "
298 "call should not happen. Do not suppress it by blindly adding "
299 "an EXPECT_CALL() if you don't mean to enforce the call. "
301 "https://github.com/google/googletest/blob/main/docs/"
302 "gmock_cook_book.md#"
303 "knowing-when-to-expect for details.\n",
304 stack_frames_to_skip);
307 Expect(
false,
nullptr, -1, msg);
311UntypedFunctionMockerBase::UntypedFunctionMockerBase()
312 : mock_obj_(nullptr), name_(
"") {}
314UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
320void UntypedFunctionMockerBase::RegisterOwner(
const void* mock_obj)
321 GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
323 MutexLock l(&g_gmock_mutex);
324 mock_obj_ = mock_obj;
326 Mock::Register(mock_obj,
this);
332void UntypedFunctionMockerBase::SetOwnerAndName(
const void* mock_obj,
334 GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
337 MutexLock l(&g_gmock_mutex);
338 mock_obj_ = mock_obj;
344const void* UntypedFunctionMockerBase::MockObject() const
345 GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
346 const void* mock_obj;
350 MutexLock l(&g_gmock_mutex);
351 Assert(mock_obj_ !=
nullptr, __FILE__, __LINE__,
352 "MockObject() must not be called before RegisterOwner() or "
353 "SetOwnerAndName() has been called.");
354 mock_obj = mock_obj_;
361const char* UntypedFunctionMockerBase::Name() const
362 GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
367 MutexLock l(&g_gmock_mutex);
368 Assert(name_ !=
nullptr, __FILE__, __LINE__,
369 "Name() must not be called before SetOwnerAndName() has "
378Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
381 for (UntypedExpectations::const_iterator it = untyped_expectations_.begin();
382 it != untyped_expectations_.end(); ++it) {
383 if (it->get() == exp) {
384 return Expectation(*it);
388 Assert(
false, __FILE__, __LINE__,
"Cannot find expectation.");
389 return Expectation();
397bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
398 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
399 g_gmock_mutex.AssertHeld();
400 bool expectations_met =
true;
401 for (UntypedExpectations::const_iterator it = untyped_expectations_.begin();
402 it != untyped_expectations_.end(); ++it) {
403 ExpectationBase* const untyped_expectation = it->get();
404 if (untyped_expectation->IsOverSaturated()) {
408 expectations_met = false;
409 }
else if (!untyped_expectation->IsSatisfied()) {
410 expectations_met = false;
411 ::std::stringstream ss;
412 ss <<
"Actual function call count doesn't match "
413 << untyped_expectation->source_text() <<
"...\n";
417 untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);
418 untyped_expectation->DescribeCallCountTo(&ss);
419 Expect(false, untyped_expectation->file(), untyped_expectation->line(),
431 UntypedExpectations expectations_to_delete;
432 untyped_expectations_.swap(expectations_to_delete);
434 g_gmock_mutex.Unlock();
435 expectations_to_delete.clear();
436 g_gmock_mutex.Lock();
438 return expectations_met;
441static CallReaction intToCallReaction(
int mock_behavior) {
442 if (mock_behavior >= kAllow && mock_behavior <= kFail) {
443 return static_cast<internal::CallReaction
>(mock_behavior);
454typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
459struct MockObjectState {
461 : first_used_file(nullptr), first_used_line(-1), leakable(false) {}
465 const char* first_used_file;
467 ::std::string first_used_test_suite;
468 ::std::string first_used_test;
470 FunctionMockers function_mockers;
477class MockObjectRegistry {
480 typedef std::map<const void*, MockObjectState> StateMap;
486 ~MockObjectRegistry() {
487 if (!GMOCK_FLAG_GET(catch_leaked_mocks))
return;
489 int leaked_count = 0;
490 for (StateMap::const_iterator it = states_.begin(); it != states_.end();
492 if (it->second.leakable)
498 const MockObjectState& state = it->second;
499 std::cout << internal::FormatFileLocation(state.first_used_file,
500 state.first_used_line);
501 std::cout <<
" ERROR: this mock object";
502 if (state.first_used_test !=
"") {
503 std::cout <<
" (used in test " << state.first_used_test_suite <<
"."
504 << state.first_used_test <<
")";
506 std::cout <<
" should be deleted but never is. Its address is @"
510 if (leaked_count > 0) {
511 std::cout <<
"\nERROR: " << leaked_count <<
" leaked mock "
512 << (leaked_count == 1 ?
"object" :
"objects")
513 <<
" found at program exit. Expectations on a mock object are "
514 "verified when the object is destructed. Leaking a mock "
515 "means that its expectations aren't verified, which is "
516 "usually a test bug. If you really intend to leak a mock, "
517 "you can suppress this error using "
518 "testing::Mock::AllowLeak(mock_object), or you may use a "
519 "fake or stub instead of a mock.\n";
526 qurt_exception_raise_fatal();
534 StateMap& states() {
return states_; }
541MockObjectRegistry g_mock_object_registry;
545std::unordered_map<uintptr_t, internal::CallReaction>&
546UninterestingCallReactionMap() {
547 static auto* map =
new std::unordered_map<uintptr_t, internal::CallReaction>;
553void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
554 internal::CallReaction reaction)
555 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
556 internal::MutexLock l(&internal::g_gmock_mutex);
557 UninterestingCallReactionMap()[mock_obj] = reaction;
564void Mock::AllowUninterestingCalls(uintptr_t mock_obj)
565 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
566 SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
571void Mock::WarnUninterestingCalls(uintptr_t mock_obj)
572 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
573 SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
578void Mock::FailUninterestingCalls(uintptr_t mock_obj)
579 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
580 SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
585void Mock::UnregisterCallReaction(uintptr_t mock_obj)
586 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
587 internal::MutexLock l(&internal::g_gmock_mutex);
588 UninterestingCallReactionMap().erase(
static_cast<uintptr_t
>(mock_obj));
593internal::CallReaction Mock::GetReactionOnUninterestingCalls(
594 const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
595 internal::MutexLock l(&internal::g_gmock_mutex);
596 return (UninterestingCallReactionMap().count(
597 reinterpret_cast<uintptr_t
>(mock_obj)) == 0)
598 ? internal::intToCallReaction(
599 GMOCK_FLAG_GET(default_mock_behavior))
600 : UninterestingCallReactionMap()[reinterpret_cast<uintptr_t>(
606void Mock::AllowLeak(
const void* mock_obj)
607 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
608 internal::MutexLock l(&internal::g_gmock_mutex);
609 g_mock_object_registry.states()[mock_obj].leakable =
true;
615bool Mock::VerifyAndClearExpectations(
void* mock_obj)
616 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
617 internal::MutexLock l(&internal::g_gmock_mutex);
618 return VerifyAndClearExpectationsLocked(mock_obj);
624bool Mock::VerifyAndClear(
void* mock_obj)
625 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
626 internal::MutexLock l(&internal::g_gmock_mutex);
627 ClearDefaultActionsLocked(mock_obj);
628 return VerifyAndClearExpectationsLocked(mock_obj);
634bool Mock::VerifyAndClearExpectationsLocked(
void* mock_obj)
635 GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
636 internal::g_gmock_mutex.AssertHeld();
637 if (g_mock_object_registry.states().count(mock_obj) == 0) {
644 bool expectations_met =
true;
645 FunctionMockers& mockers =
646 g_mock_object_registry.states()[mock_obj].function_mockers;
647 for (FunctionMockers::const_iterator it = mockers.begin();
648 it != mockers.end(); ++it) {
649 if (!(*it)->VerifyAndClearExpectationsLocked()) {
650 expectations_met =
false;
656 return expectations_met;
659bool Mock::IsNaggy(
void* mock_obj)
660 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
661 return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn;
663bool Mock::IsNice(
void* mock_obj)
664 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
665 return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow;
667bool Mock::IsStrict(
void* mock_obj)
668 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
669 return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail;
673void Mock::Register(
const void* mock_obj,
674 internal::UntypedFunctionMockerBase* mocker)
675 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
676 internal::MutexLock l(&internal::g_gmock_mutex);
677 g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
683void Mock::RegisterUseByOnCallOrExpectCall(
const void* mock_obj,
684 const char* file,
int line)
685 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
686 internal::MutexLock l(&internal::g_gmock_mutex);
687 MockObjectState& state = g_mock_object_registry.states()[mock_obj];
688 if (state.first_used_file ==
nullptr) {
689 state.first_used_file = file;
690 state.first_used_line = line;
691 const TestInfo*
const test_info =
692 UnitTest::GetInstance()->current_test_info();
693 if (test_info !=
nullptr) {
694 state.first_used_test_suite = test_info->test_suite_name();
695 state.first_used_test = test_info->name();
704void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
705 GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
706 internal::g_gmock_mutex.AssertHeld();
707 for (MockObjectRegistry::StateMap::iterator it =
708 g_mock_object_registry.states().begin();
709 it != g_mock_object_registry.states().end(); ++it) {
710 FunctionMockers& mockers = it->second.function_mockers;
711 if (mockers.erase(mocker) > 0) {
713 if (mockers.empty()) {
714 g_mock_object_registry.states().erase(it);
722void Mock::ClearDefaultActionsLocked(
void* mock_obj)
723 GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
724 internal::g_gmock_mutex.AssertHeld();
726 if (g_mock_object_registry.states().count(mock_obj) == 0) {
733 FunctionMockers& mockers =
734 g_mock_object_registry.states()[mock_obj].function_mockers;
735 for (FunctionMockers::const_iterator it = mockers.begin();
736 it != mockers.end(); ++it) {
737 (*it)->ClearDefaultActionsLocked();
744Expectation::Expectation() {}
746Expectation::Expectation(
747 const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
748 : expectation_base_(an_expectation_base) {}
750Expectation::~Expectation() {}
753void Sequence::AddExpectation(
const Expectation& expectation)
const {
754 if (*last_expectation_ != expectation) {
755 if (last_expectation_->expectation_base() !=
nullptr) {
756 expectation.expectation_base()->immediate_prerequisites_ +=
759 *last_expectation_ = expectation;
764InSequence::InSequence() {
765 if (internal::g_gmock_implicit_sequence.get() ==
nullptr) {
766 internal::g_gmock_implicit_sequence.set(
new Sequence);
767 sequence_created_ =
true;
769 sequence_created_ =
false;
775InSequence::~InSequence() {
776 if (sequence_created_) {
777 delete internal::g_gmock_implicit_sequence.get();
778 internal::g_gmock_implicit_sequence.set(
nullptr);