blob: 353bb2dfe9be13b3d0267124bc5e40ce102dea04 [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
39#include <set>
40#include <gtest/gtest.h>
41
42namespace testing {
43namespace internal {
44
45// Protects the mock object registry (in class Mock), all function
46// mockers, and all expectations.
47Mutex g_gmock_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
48
49// Constructs an ExpectationBase object.
50ExpectationBase::ExpectationBase(const char* file, int line)
51 : file_(file),
52 line_(line),
53 cardinality_specified_(false),
54 cardinality_(Exactly(1)),
55 call_count_(0),
56 retired_(false) {
57}
58
59// Destructs an ExpectationBase object.
60ExpectationBase::~ExpectationBase() {}
61
62// Explicitly specifies the cardinality of this expectation. Used by
63// the subclasses to implement the .Times() clause.
64void ExpectationBase::SpecifyCardinality(const Cardinality& cardinality) {
65 cardinality_specified_ = true;
66 cardinality_ = cardinality;
67}
68
69// Retires all pre-requisites of this expectation.
70void ExpectationBase::RetireAllPreRequisites() {
71 if (is_retired()) {
72 // We can take this short-cut as we never retire an expectation
73 // until we have retired all its pre-requisites.
74 return;
75 }
76
77 for (ExpectationBaseSet::const_iterator it =
78 immediate_prerequisites_.begin();
79 it != immediate_prerequisites_.end();
80 ++it) {
81 ExpectationBase* const prerequisite = (*it).get();
82 if (!prerequisite->is_retired()) {
83 prerequisite->RetireAllPreRequisites();
84 prerequisite->Retire();
85 }
86 }
87}
88
89// Returns true iff all pre-requisites of this expectation have been
90// satisfied.
91// L >= g_gmock_mutex
92bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
93 g_gmock_mutex.AssertHeld();
94 for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
95 it != immediate_prerequisites_.end(); ++it) {
96 if (!(*it)->IsSatisfied() ||
97 !(*it)->AllPrerequisitesAreSatisfied())
98 return false;
99 }
100 return true;
101}
102
103// Adds unsatisfied pre-requisites of this expectation to 'result'.
104// L >= g_gmock_mutex
105void ExpectationBase::FindUnsatisfiedPrerequisites(
106 ExpectationBaseSet* result) const {
107 g_gmock_mutex.AssertHeld();
108 for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
109 it != immediate_prerequisites_.end(); ++it) {
110 if ((*it)->IsSatisfied()) {
111 // If *it is satisfied and has a call count of 0, some of its
112 // pre-requisites may not be satisfied yet.
113 if ((*it)->call_count_ == 0) {
114 (*it)->FindUnsatisfiedPrerequisites(result);
115 }
116 } else {
117 // Now that we know *it is unsatisfied, we are not so interested
118 // in whether its pre-requisites are satisfied. Therefore we
119 // don't recursively call FindUnsatisfiedPrerequisites() here.
120 result->insert(*it);
121 }
122 }
123}
124
125// Points to the implicit sequence introduced by a living InSequence
126// object (if any) in the current thread or NULL.
127ThreadLocal<Sequence*> g_gmock_implicit_sequence;
128
129// Reports an uninteresting call (whose description is in msg) in the
130// manner specified by 'reaction'.
131void ReportUninterestingCall(CallReaction reaction, const string& msg) {
132 switch (reaction) {
133 case ALLOW:
134 Log(INFO, msg, 4);
135 break;
136 case WARN:
137 Log(WARNING, msg, 4);
138 break;
139 default: // FAIL
140 Expect(false, NULL, -1, msg);
141 }
142}
143
144} // namespace internal
145
146// Class Mock.
147
148namespace {
149
150typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
151typedef std::map<const void*, FunctionMockers> MockObjectRegistry;
152
153// Maps a mock object to the set of mock methods it owns. Protected
154// by g_gmock_mutex.
155MockObjectRegistry g_mock_object_registry;
156
157// Maps a mock object to the reaction Google Mock should have when an
158// uninteresting method is called. Protected by g_gmock_mutex.
159std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
160
161// Sets the reaction Google Mock should have when an uninteresting
162// method of the given mock object is called.
163// L < g_gmock_mutex
164void SetReactionOnUninterestingCalls(const void* mock_obj,
165 internal::CallReaction reaction) {
166 internal::MutexLock l(&internal::g_gmock_mutex);
167 g_uninteresting_call_reaction[mock_obj] = reaction;
168}
169
170} // namespace
171
172// Tells Google Mock to allow uninteresting calls on the given mock
173// object.
174// L < g_gmock_mutex
175void Mock::AllowUninterestingCalls(const void* mock_obj) {
176 SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW);
177}
178
179// Tells Google Mock to warn the user about uninteresting calls on the
180// given mock object.
181// L < g_gmock_mutex
182void Mock::WarnUninterestingCalls(const void* mock_obj) {
183 SetReactionOnUninterestingCalls(mock_obj, internal::WARN);
184}
185
186// Tells Google Mock to fail uninteresting calls on the given mock
187// object.
188// L < g_gmock_mutex
189void Mock::FailUninterestingCalls(const void* mock_obj) {
190 SetReactionOnUninterestingCalls(mock_obj, internal::FAIL);
191}
192
193// Tells Google Mock the given mock object is being destroyed and its
194// entry in the call-reaction table should be removed.
195// L < g_gmock_mutex
196void Mock::UnregisterCallReaction(const void* mock_obj) {
197 internal::MutexLock l(&internal::g_gmock_mutex);
198 g_uninteresting_call_reaction.erase(mock_obj);
199}
200
201// Returns the reaction Google Mock will have on uninteresting calls
202// made on the given mock object.
203// L < g_gmock_mutex
204internal::CallReaction Mock::GetReactionOnUninterestingCalls(
205 const void* mock_obj) {
206 internal::MutexLock l(&internal::g_gmock_mutex);
207 return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
208 internal::WARN : g_uninteresting_call_reaction[mock_obj];
209}
210
211// Verifies and clears all expectations on the given mock object. If
212// the expectations aren't satisfied, generates one or more Google
213// Test non-fatal failures and returns false.
214// L < g_gmock_mutex
215bool Mock::VerifyAndClearExpectations(void* mock_obj) {
216 internal::MutexLock l(&internal::g_gmock_mutex);
217 return VerifyAndClearExpectationsLocked(mock_obj);
218}
219
220// Verifies all expectations on the given mock object and clears its
221// default actions and expectations. Returns true iff the
222// verification was successful.
223// L < g_gmock_mutex
224bool Mock::VerifyAndClear(void* mock_obj) {
225 internal::MutexLock l(&internal::g_gmock_mutex);
226 ClearDefaultActionsLocked(mock_obj);
227 return VerifyAndClearExpectationsLocked(mock_obj);
228}
229
230// Verifies and clears all expectations on the given mock object. If
231// the expectations aren't satisfied, generates one or more Google
232// Test non-fatal failures and returns false.
233// L >= g_gmock_mutex
234bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
235 internal::g_gmock_mutex.AssertHeld();
236 if (g_mock_object_registry.count(mock_obj) == 0) {
237 // No EXPECT_CALL() was set on the given mock object.
238 return true;
239 }
240
241 // Verifies and clears the expectations on each mock method in the
242 // given mock object.
243 bool expectations_met = true;
244 FunctionMockers& mockers = g_mock_object_registry[mock_obj];
245 for (FunctionMockers::const_iterator it = mockers.begin();
246 it != mockers.end(); ++it) {
247 if (!(*it)->VerifyAndClearExpectationsLocked()) {
248 expectations_met = false;
249 }
250 }
251
252 // We don't clear the content of mockers, as they may still be
253 // needed by ClearDefaultActionsLocked().
254 return expectations_met;
255}
256
257// Registers a mock object and a mock method it owns.
258// L < g_gmock_mutex
259void Mock::Register(const void* mock_obj,
260 internal::UntypedFunctionMockerBase* mocker) {
261 internal::MutexLock l(&internal::g_gmock_mutex);
262 g_mock_object_registry[mock_obj].insert(mocker);
263}
264
265// Unregisters a mock method; removes the owning mock object from the
266// registry when the last mock method associated with it has been
267// unregistered. This is called only in the destructor of
268// FunctionMockerBase.
269// L >= g_gmock_mutex
270void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
271 internal::g_gmock_mutex.AssertHeld();
272 for (MockObjectRegistry::iterator it = g_mock_object_registry.begin();
273 it != g_mock_object_registry.end(); ++it) {
274 FunctionMockers& mockers = it->second;
275 if (mockers.erase(mocker) > 0) {
276 // mocker was in mockers and has been just removed.
277 if (mockers.empty()) {
278 g_mock_object_registry.erase(it);
279 }
280 return;
281 }
282 }
283}
284
285// Clears all ON_CALL()s set on the given mock object.
286// L >= g_gmock_mutex
287void Mock::ClearDefaultActionsLocked(void* mock_obj) {
288 internal::g_gmock_mutex.AssertHeld();
289
290 if (g_mock_object_registry.count(mock_obj) == 0) {
291 // No ON_CALL() was set on the given mock object.
292 return;
293 }
294
295 // Clears the default actions for each mock method in the given mock
296 // object.
297 FunctionMockers& mockers = g_mock_object_registry[mock_obj];
298 for (FunctionMockers::const_iterator it = mockers.begin();
299 it != mockers.end(); ++it) {
300 (*it)->ClearDefaultActionsLocked();
301 }
302
303 // We don't clear the content of mockers, as they may still be
304 // needed by VerifyAndClearExpectationsLocked().
305}
306
307// Adds an expectation to a sequence.
308void Sequence::AddExpectation(
309 const internal::linked_ptr<internal::ExpectationBase>& expectation) const {
310 if (*last_expectation_ != expectation) {
311 if (*last_expectation_ != NULL) {
312 expectation->immediate_prerequisites_.insert(*last_expectation_);
313 }
314 *last_expectation_ = expectation;
315 }
316}
317
318// Creates the implicit sequence if there isn't one.
319InSequence::InSequence() {
320 if (internal::g_gmock_implicit_sequence.get() == NULL) {
321 internal::g_gmock_implicit_sequence.set(new Sequence);
322 sequence_created_ = true;
323 } else {
324 sequence_created_ = false;
325 }
326}
327
328// Deletes the implicit sequence if it was created by the constructor
329// of this object.
330InSequence::~InSequence() {
331 if (sequence_created_) {
332 delete internal::g_gmock_implicit_sequence.get();
333 internal::g_gmock_implicit_sequence.set(NULL);
334 }
335}
336
337} // namespace testing