blob: 02a3227fb13d50631b97a1682baac0b821daf901 [file] [log] [blame]
shiqiane35fdd92008-12-10 05:08:54 +00001// Copyright 2007, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Author: wan@google.com (Zhanyong Wan)
31
32// Google Mock - a framework for writing C++ mock classes.
33//
34// This file implements the spec builder syntax (ON_CALL and
35// EXPECT_CALL).
36
37#include <gmock/gmock-spec-builders.h>
38
zhanyong.wandf35a762009-04-22 22:25:31 +000039#include <stdlib.h>
40#include <iostream> // NOLINT
41#include <map>
shiqiane35fdd92008-12-10 05:08:54 +000042#include <set>
vladlosev6c54a5e2009-10-21 06:15:34 +000043#include <string>
zhanyong.wandf35a762009-04-22 22:25:31 +000044#include <gmock/gmock.h>
shiqiane35fdd92008-12-10 05:08:54 +000045#include <gtest/gtest.h>
46
zhanyong.wandf35a762009-04-22 22:25:31 +000047#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
48#include <unistd.h> // NOLINT
49#endif
50
shiqiane35fdd92008-12-10 05:08:54 +000051namespace testing {
52namespace internal {
53
54// Protects the mock object registry (in class Mock), all function
55// mockers, and all expectations.
56Mutex g_gmock_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
57
58// Constructs an ExpectationBase object.
zhanyong.wan32de5f52009-12-23 00:13:23 +000059ExpectationBase::ExpectationBase(const char* a_file,
60 int a_line,
61 const string& a_source_text)
62 : file_(a_file),
63 line_(a_line),
64 source_text_(a_source_text),
shiqiane35fdd92008-12-10 05:08:54 +000065 cardinality_specified_(false),
66 cardinality_(Exactly(1)),
67 call_count_(0),
68 retired_(false) {
69}
70
71// Destructs an ExpectationBase object.
72ExpectationBase::~ExpectationBase() {}
73
74// Explicitly specifies the cardinality of this expectation. Used by
75// the subclasses to implement the .Times() clause.
zhanyong.wan32de5f52009-12-23 00:13:23 +000076void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {
shiqiane35fdd92008-12-10 05:08:54 +000077 cardinality_specified_ = true;
zhanyong.wan32de5f52009-12-23 00:13:23 +000078 cardinality_ = a_cardinality;
shiqiane35fdd92008-12-10 05:08:54 +000079}
80
81// Retires all pre-requisites of this expectation.
82void ExpectationBase::RetireAllPreRequisites() {
83 if (is_retired()) {
84 // We can take this short-cut as we never retire an expectation
85 // until we have retired all its pre-requisites.
86 return;
87 }
88
zhanyong.wan41b9b0b2009-07-01 19:04:51 +000089 for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
90 it != immediate_prerequisites_.end(); ++it) {
91 ExpectationBase* const prerequisite = it->expectation_base().get();
shiqiane35fdd92008-12-10 05:08:54 +000092 if (!prerequisite->is_retired()) {
93 prerequisite->RetireAllPreRequisites();
94 prerequisite->Retire();
95 }
96 }
97}
98
99// Returns true iff all pre-requisites of this expectation have been
100// satisfied.
101// L >= g_gmock_mutex
102bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
103 g_gmock_mutex.AssertHeld();
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000104 for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
shiqiane35fdd92008-12-10 05:08:54 +0000105 it != immediate_prerequisites_.end(); ++it) {
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000106 if (!(it->expectation_base()->IsSatisfied()) ||
107 !(it->expectation_base()->AllPrerequisitesAreSatisfied()))
shiqiane35fdd92008-12-10 05:08:54 +0000108 return false;
109 }
110 return true;
111}
112
113// Adds unsatisfied pre-requisites of this expectation to 'result'.
114// L >= g_gmock_mutex
115void ExpectationBase::FindUnsatisfiedPrerequisites(
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000116 ExpectationSet* result) const {
shiqiane35fdd92008-12-10 05:08:54 +0000117 g_gmock_mutex.AssertHeld();
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000118 for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
shiqiane35fdd92008-12-10 05:08:54 +0000119 it != immediate_prerequisites_.end(); ++it) {
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000120 if (it->expectation_base()->IsSatisfied()) {
shiqiane35fdd92008-12-10 05:08:54 +0000121 // If *it is satisfied and has a call count of 0, some of its
122 // pre-requisites may not be satisfied yet.
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000123 if (it->expectation_base()->call_count_ == 0) {
124 it->expectation_base()->FindUnsatisfiedPrerequisites(result);
shiqiane35fdd92008-12-10 05:08:54 +0000125 }
126 } else {
127 // Now that we know *it is unsatisfied, we are not so interested
128 // in whether its pre-requisites are satisfied. Therefore we
129 // don't recursively call FindUnsatisfiedPrerequisites() here.
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000130 *result += *it;
shiqiane35fdd92008-12-10 05:08:54 +0000131 }
132 }
133}
134
135// Points to the implicit sequence introduced by a living InSequence
136// object (if any) in the current thread or NULL.
137ThreadLocal<Sequence*> g_gmock_implicit_sequence;
138
139// Reports an uninteresting call (whose description is in msg) in the
140// manner specified by 'reaction'.
141void ReportUninterestingCall(CallReaction reaction, const string& msg) {
142 switch (reaction) {
143 case ALLOW:
zhanyong.wan9413f2f2009-05-29 19:50:06 +0000144 Log(INFO, msg, 3);
shiqiane35fdd92008-12-10 05:08:54 +0000145 break;
146 case WARN:
zhanyong.wan9413f2f2009-05-29 19:50:06 +0000147 Log(WARNING, msg, 3);
shiqiane35fdd92008-12-10 05:08:54 +0000148 break;
149 default: // FAIL
150 Expect(false, NULL, -1, msg);
151 }
152}
153
154} // namespace internal
155
156// Class Mock.
157
158namespace {
159
160typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
shiqiane35fdd92008-12-10 05:08:54 +0000161
zhanyong.wandf35a762009-04-22 22:25:31 +0000162// The current state of a mock object. Such information is needed for
163// detecting leaked mock objects and explicitly verifying a mock's
164// expectations.
165struct MockObjectState {
166 MockObjectState()
167 : first_used_file(NULL), first_used_line(-1), leakable(false) {}
168
169 // Where in the source file an ON_CALL or EXPECT_CALL is first
170 // invoked on this mock object.
171 const char* first_used_file;
172 int first_used_line;
zhanyong.wane7bb5ed2009-05-05 23:14:47 +0000173 ::std::string first_used_test_case;
174 ::std::string first_used_test;
zhanyong.wandf35a762009-04-22 22:25:31 +0000175 bool leakable; // true iff it's OK to leak the object.
176 FunctionMockers function_mockers; // All registered methods of the object.
177};
178
179// A global registry holding the state of all mock objects that are
180// alive. A mock object is added to this registry the first time
181// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
182// is removed from the registry in the mock object's destructor.
183class MockObjectRegistry {
184 public:
185 // Maps a mock object (identified by its address) to its state.
186 typedef std::map<const void*, MockObjectState> StateMap;
187
188 // This destructor will be called when a program exits, after all
189 // tests in it have been run. By then, there should be no mock
190 // object alive. Therefore we report any living object as test
191 // failure, unless the user explicitly asked us to ignore it.
192 ~MockObjectRegistry() {
zhanyong.wan9571b282009-08-07 07:15:56 +0000193
194 // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
195 // a macro.
zhanyong.wandf35a762009-04-22 22:25:31 +0000196
197 if (!GMOCK_FLAG(catch_leaked_mocks))
198 return;
199
200 int leaked_count = 0;
201 for (StateMap::const_iterator it = states_.begin(); it != states_.end();
202 ++it) {
203 if (it->second.leakable) // The user said it's fine to leak this object.
204 continue;
205
206 // TODO(wan@google.com): Print the type of the leaked object.
207 // This can help the user identify the leaked object.
zhanyong.wan9571b282009-08-07 07:15:56 +0000208 std::cout << "\n";
zhanyong.wandf35a762009-04-22 22:25:31 +0000209 const MockObjectState& state = it->second;
zhanyong.wanf5e1ce52009-09-16 07:02:02 +0000210 std::cout << internal::FormatFileLocation(state.first_used_file,
211 state.first_used_line);
zhanyong.wan9571b282009-08-07 07:15:56 +0000212 std::cout << " ERROR: this mock object";
zhanyong.wane7bb5ed2009-05-05 23:14:47 +0000213 if (state.first_used_test != "") {
zhanyong.wan9571b282009-08-07 07:15:56 +0000214 std::cout << " (used in test " << state.first_used_test_case << "."
zhanyong.wane7bb5ed2009-05-05 23:14:47 +0000215 << state.first_used_test << ")";
216 }
zhanyong.wan9571b282009-08-07 07:15:56 +0000217 std::cout << " should be deleted but never is. Its address is @"
zhanyong.wane7bb5ed2009-05-05 23:14:47 +0000218 << it->first << ".";
zhanyong.wandf35a762009-04-22 22:25:31 +0000219 leaked_count++;
220 }
221 if (leaked_count > 0) {
zhanyong.wan9571b282009-08-07 07:15:56 +0000222 std::cout << "\nERROR: " << leaked_count
zhanyong.wandf35a762009-04-22 22:25:31 +0000223 << " leaked mock " << (leaked_count == 1 ? "object" : "objects")
224 << " found at program exit.\n";
zhanyong.wan9571b282009-08-07 07:15:56 +0000225 std::cout.flush();
zhanyong.wandf35a762009-04-22 22:25:31 +0000226 ::std::cerr.flush();
227 // RUN_ALL_TESTS() has already returned when this destructor is
228 // called. Therefore we cannot use the normal Google Test
229 // failure reporting mechanism.
230 _exit(1); // We cannot call exit() as it is not reentrant and
231 // may already have been called.
232 }
233 }
234
235 StateMap& states() { return states_; }
236 private:
237 StateMap states_;
238};
239
240// Protected by g_gmock_mutex.
shiqiane35fdd92008-12-10 05:08:54 +0000241MockObjectRegistry g_mock_object_registry;
242
243// Maps a mock object to the reaction Google Mock should have when an
244// uninteresting method is called. Protected by g_gmock_mutex.
245std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
246
247// Sets the reaction Google Mock should have when an uninteresting
248// method of the given mock object is called.
249// L < g_gmock_mutex
250void SetReactionOnUninterestingCalls(const void* mock_obj,
251 internal::CallReaction reaction) {
252 internal::MutexLock l(&internal::g_gmock_mutex);
253 g_uninteresting_call_reaction[mock_obj] = reaction;
254}
255
256} // namespace
257
258// Tells Google Mock to allow uninteresting calls on the given mock
259// object.
260// L < g_gmock_mutex
261void Mock::AllowUninterestingCalls(const void* mock_obj) {
262 SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW);
263}
264
265// Tells Google Mock to warn the user about uninteresting calls on the
266// given mock object.
267// L < g_gmock_mutex
268void Mock::WarnUninterestingCalls(const void* mock_obj) {
269 SetReactionOnUninterestingCalls(mock_obj, internal::WARN);
270}
271
272// Tells Google Mock to fail uninteresting calls on the given mock
273// object.
274// L < g_gmock_mutex
275void Mock::FailUninterestingCalls(const void* mock_obj) {
276 SetReactionOnUninterestingCalls(mock_obj, internal::FAIL);
277}
278
279// Tells Google Mock the given mock object is being destroyed and its
280// entry in the call-reaction table should be removed.
281// L < g_gmock_mutex
282void Mock::UnregisterCallReaction(const void* mock_obj) {
283 internal::MutexLock l(&internal::g_gmock_mutex);
284 g_uninteresting_call_reaction.erase(mock_obj);
285}
286
287// Returns the reaction Google Mock will have on uninteresting calls
288// made on the given mock object.
289// L < g_gmock_mutex
290internal::CallReaction Mock::GetReactionOnUninterestingCalls(
291 const void* mock_obj) {
292 internal::MutexLock l(&internal::g_gmock_mutex);
293 return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
294 internal::WARN : g_uninteresting_call_reaction[mock_obj];
295}
296
zhanyong.wandf35a762009-04-22 22:25:31 +0000297// Tells Google Mock to ignore mock_obj when checking for leaked mock
298// objects.
299// L < g_gmock_mutex
300void Mock::AllowLeak(const void* mock_obj) {
301 internal::MutexLock l(&internal::g_gmock_mutex);
302 g_mock_object_registry.states()[mock_obj].leakable = true;
303}
304
shiqiane35fdd92008-12-10 05:08:54 +0000305// Verifies and clears all expectations on the given mock object. If
306// the expectations aren't satisfied, generates one or more Google
307// Test non-fatal failures and returns false.
308// L < g_gmock_mutex
309bool Mock::VerifyAndClearExpectations(void* mock_obj) {
310 internal::MutexLock l(&internal::g_gmock_mutex);
311 return VerifyAndClearExpectationsLocked(mock_obj);
312}
313
314// Verifies all expectations on the given mock object and clears its
315// default actions and expectations. Returns true iff the
316// verification was successful.
317// L < g_gmock_mutex
318bool Mock::VerifyAndClear(void* mock_obj) {
319 internal::MutexLock l(&internal::g_gmock_mutex);
320 ClearDefaultActionsLocked(mock_obj);
321 return VerifyAndClearExpectationsLocked(mock_obj);
322}
323
324// Verifies and clears all expectations on the given mock object. If
325// the expectations aren't satisfied, generates one or more Google
326// Test non-fatal failures and returns false.
327// L >= g_gmock_mutex
328bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
329 internal::g_gmock_mutex.AssertHeld();
zhanyong.wandf35a762009-04-22 22:25:31 +0000330 if (g_mock_object_registry.states().count(mock_obj) == 0) {
shiqiane35fdd92008-12-10 05:08:54 +0000331 // No EXPECT_CALL() was set on the given mock object.
332 return true;
333 }
334
335 // Verifies and clears the expectations on each mock method in the
336 // given mock object.
337 bool expectations_met = true;
zhanyong.wandf35a762009-04-22 22:25:31 +0000338 FunctionMockers& mockers =
339 g_mock_object_registry.states()[mock_obj].function_mockers;
shiqiane35fdd92008-12-10 05:08:54 +0000340 for (FunctionMockers::const_iterator it = mockers.begin();
341 it != mockers.end(); ++it) {
342 if (!(*it)->VerifyAndClearExpectationsLocked()) {
343 expectations_met = false;
344 }
345 }
346
347 // We don't clear the content of mockers, as they may still be
348 // needed by ClearDefaultActionsLocked().
349 return expectations_met;
350}
351
352// Registers a mock object and a mock method it owns.
353// L < g_gmock_mutex
354void Mock::Register(const void* mock_obj,
355 internal::UntypedFunctionMockerBase* mocker) {
356 internal::MutexLock l(&internal::g_gmock_mutex);
zhanyong.wandf35a762009-04-22 22:25:31 +0000357 g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
358}
359
360// Tells Google Mock where in the source code mock_obj is used in an
361// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
362// information helps the user identify which object it is.
363// L < g_gmock_mutex
364void Mock::RegisterUseByOnCallOrExpectCall(
365 const void* mock_obj, const char* file, int line) {
366 internal::MutexLock l(&internal::g_gmock_mutex);
367 MockObjectState& state = g_mock_object_registry.states()[mock_obj];
368 if (state.first_used_file == NULL) {
369 state.first_used_file = file;
370 state.first_used_line = line;
zhanyong.wane7bb5ed2009-05-05 23:14:47 +0000371 const TestInfo* const test_info =
372 UnitTest::GetInstance()->current_test_info();
373 if (test_info != NULL) {
374 // TODO(wan@google.com): record the test case name when the
375 // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
376 // TearDownTestCase().
377 state.first_used_test_case = test_info->test_case_name();
378 state.first_used_test = test_info->name();
379 }
zhanyong.wandf35a762009-04-22 22:25:31 +0000380 }
shiqiane35fdd92008-12-10 05:08:54 +0000381}
382
383// Unregisters a mock method; removes the owning mock object from the
384// registry when the last mock method associated with it has been
385// unregistered. This is called only in the destructor of
386// FunctionMockerBase.
387// L >= g_gmock_mutex
388void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
389 internal::g_gmock_mutex.AssertHeld();
zhanyong.wandf35a762009-04-22 22:25:31 +0000390 for (MockObjectRegistry::StateMap::iterator it =
391 g_mock_object_registry.states().begin();
392 it != g_mock_object_registry.states().end(); ++it) {
393 FunctionMockers& mockers = it->second.function_mockers;
shiqiane35fdd92008-12-10 05:08:54 +0000394 if (mockers.erase(mocker) > 0) {
395 // mocker was in mockers and has been just removed.
396 if (mockers.empty()) {
zhanyong.wandf35a762009-04-22 22:25:31 +0000397 g_mock_object_registry.states().erase(it);
shiqiane35fdd92008-12-10 05:08:54 +0000398 }
399 return;
400 }
401 }
402}
403
404// Clears all ON_CALL()s set on the given mock object.
405// L >= g_gmock_mutex
406void Mock::ClearDefaultActionsLocked(void* mock_obj) {
407 internal::g_gmock_mutex.AssertHeld();
408
zhanyong.wandf35a762009-04-22 22:25:31 +0000409 if (g_mock_object_registry.states().count(mock_obj) == 0) {
shiqiane35fdd92008-12-10 05:08:54 +0000410 // No ON_CALL() was set on the given mock object.
411 return;
412 }
413
414 // Clears the default actions for each mock method in the given mock
415 // object.
zhanyong.wandf35a762009-04-22 22:25:31 +0000416 FunctionMockers& mockers =
417 g_mock_object_registry.states()[mock_obj].function_mockers;
shiqiane35fdd92008-12-10 05:08:54 +0000418 for (FunctionMockers::const_iterator it = mockers.begin();
419 it != mockers.end(); ++it) {
420 (*it)->ClearDefaultActionsLocked();
421 }
422
423 // We don't clear the content of mockers, as they may still be
424 // needed by VerifyAndClearExpectationsLocked().
425}
426
zhanyong.wan7c95d832009-10-01 21:56:16 +0000427Expectation::Expectation() {}
428
429Expectation::Expectation(
zhanyong.wan32de5f52009-12-23 00:13:23 +0000430 const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base)
431 : expectation_base_(an_expectation_base) {}
zhanyong.wan7c95d832009-10-01 21:56:16 +0000432
433Expectation::~Expectation() {}
434
shiqiane35fdd92008-12-10 05:08:54 +0000435// Adds an expectation to a sequence.
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000436void Sequence::AddExpectation(const Expectation& expectation) const {
shiqiane35fdd92008-12-10 05:08:54 +0000437 if (*last_expectation_ != expectation) {
zhanyong.wan41b9b0b2009-07-01 19:04:51 +0000438 if (last_expectation_->expectation_base() != NULL) {
439 expectation.expectation_base()->immediate_prerequisites_
440 += *last_expectation_;
shiqiane35fdd92008-12-10 05:08:54 +0000441 }
442 *last_expectation_ = expectation;
443 }
444}
445
446// Creates the implicit sequence if there isn't one.
447InSequence::InSequence() {
448 if (internal::g_gmock_implicit_sequence.get() == NULL) {
449 internal::g_gmock_implicit_sequence.set(new Sequence);
450 sequence_created_ = true;
451 } else {
452 sequence_created_ = false;
453 }
454}
455
456// Deletes the implicit sequence if it was created by the constructor
457// of this object.
458InSequence::~InSequence() {
459 if (sequence_created_) {
460 delete internal::g_gmock_implicit_sequence.get();
461 internal::g_gmock_implicit_sequence.set(NULL);
462 }
463}
464
465} // namespace testing