OLD | NEW |
| (Empty) |
1 // 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 <stdlib.h> | |
40 #include <iostream> // NOLINT | |
41 #include <map> | |
42 #include <set> | |
43 #include <string> | |
44 #include <gmock/gmock.h> | |
45 #include <gtest/gtest.h> | |
46 | |
47 #if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC | |
48 #include <unistd.h> // NOLINT | |
49 #endif | |
50 | |
51 namespace testing { | |
52 namespace internal { | |
53 | |
54 // Protects the mock object registry (in class Mock), all function | |
55 // mockers, and all expectations. | |
56 GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); | |
57 | |
58 // Constructs an ExpectationBase object. | |
59 ExpectationBase::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), | |
65 cardinality_specified_(false), | |
66 cardinality_(Exactly(1)), | |
67 call_count_(0), | |
68 retired_(false) { | |
69 } | |
70 | |
71 // Destructs an ExpectationBase object. | |
72 ExpectationBase::~ExpectationBase() {} | |
73 | |
74 // Explicitly specifies the cardinality of this expectation. Used by | |
75 // the subclasses to implement the .Times() clause. | |
76 void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) { | |
77 cardinality_specified_ = true; | |
78 cardinality_ = a_cardinality; | |
79 } | |
80 | |
81 // Retires all pre-requisites of this expectation. | |
82 void 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 | |
89 for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); | |
90 it != immediate_prerequisites_.end(); ++it) { | |
91 ExpectationBase* const prerequisite = it->expectation_base().get(); | |
92 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 | |
102 bool ExpectationBase::AllPrerequisitesAreSatisfied() const { | |
103 g_gmock_mutex.AssertHeld(); | |
104 for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); | |
105 it != immediate_prerequisites_.end(); ++it) { | |
106 if (!(it->expectation_base()->IsSatisfied()) || | |
107 !(it->expectation_base()->AllPrerequisitesAreSatisfied())) | |
108 return false; | |
109 } | |
110 return true; | |
111 } | |
112 | |
113 // Adds unsatisfied pre-requisites of this expectation to 'result'. | |
114 // L >= g_gmock_mutex | |
115 void ExpectationBase::FindUnsatisfiedPrerequisites( | |
116 ExpectationSet* result) const { | |
117 g_gmock_mutex.AssertHeld(); | |
118 for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); | |
119 it != immediate_prerequisites_.end(); ++it) { | |
120 if (it->expectation_base()->IsSatisfied()) { | |
121 // If *it is satisfied and has a call count of 0, some of its | |
122 // pre-requisites may not be satisfied yet. | |
123 if (it->expectation_base()->call_count_ == 0) { | |
124 it->expectation_base()->FindUnsatisfiedPrerequisites(result); | |
125 } | |
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. | |
130 *result += *it; | |
131 } | |
132 } | |
133 } | |
134 | |
135 // Points to the implicit sequence introduced by a living InSequence | |
136 // object (if any) in the current thread or NULL. | |
137 ThreadLocal<Sequence*> g_gmock_implicit_sequence; | |
138 | |
139 // Reports an uninteresting call (whose description is in msg) in the | |
140 // manner specified by 'reaction'. | |
141 void ReportUninterestingCall(CallReaction reaction, const string& msg) { | |
142 switch (reaction) { | |
143 case ALLOW: | |
144 Log(INFO, msg, 3); | |
145 break; | |
146 case WARN: | |
147 Log(WARNING, msg, 3); | |
148 break; | |
149 default: // FAIL | |
150 Expect(false, NULL, -1, msg); | |
151 } | |
152 } | |
153 | |
154 } // namespace internal | |
155 | |
156 // Class Mock. | |
157 | |
158 namespace { | |
159 | |
160 typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers; | |
161 | |
162 // 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. | |
165 struct 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; | |
173 ::std::string first_used_test_case; | |
174 ::std::string first_used_test; | |
175 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. | |
183 class 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() { | |
193 | |
194 // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is | |
195 // a macro. | |
196 | |
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. | |
208 std::cout << "\n"; | |
209 const MockObjectState& state = it->second; | |
210 std::cout << internal::FormatFileLocation(state.first_used_file, | |
211 state.first_used_line); | |
212 std::cout << " ERROR: this mock object"; | |
213 if (state.first_used_test != "") { | |
214 std::cout << " (used in test " << state.first_used_test_case << "." | |
215 << state.first_used_test << ")"; | |
216 } | |
217 std::cout << " should be deleted but never is. Its address is @" | |
218 << it->first << "."; | |
219 leaked_count++; | |
220 } | |
221 if (leaked_count > 0) { | |
222 std::cout << "\nERROR: " << leaked_count | |
223 << " leaked mock " << (leaked_count == 1 ? "object" : "objects") | |
224 << " found at program exit.\n"; | |
225 std::cout.flush(); | |
226 ::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. | |
241 MockObjectRegistry 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. | |
245 std::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 | |
250 void 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 | |
261 void 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 | |
268 void 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 | |
275 void 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 | |
282 void 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 | |
290 internal::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 | |
297 // Tells Google Mock to ignore mock_obj when checking for leaked mock | |
298 // objects. | |
299 // L < g_gmock_mutex | |
300 void 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 | |
305 // 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 | |
309 bool 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 | |
318 bool 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 | |
328 bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) { | |
329 internal::g_gmock_mutex.AssertHeld(); | |
330 if (g_mock_object_registry.states().count(mock_obj) == 0) { | |
331 // 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; | |
338 FunctionMockers& mockers = | |
339 g_mock_object_registry.states()[mock_obj].function_mockers; | |
340 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 | |
354 void Mock::Register(const void* mock_obj, | |
355 internal::UntypedFunctionMockerBase* mocker) { | |
356 internal::MutexLock l(&internal::g_gmock_mutex); | |
357 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 | |
364 void 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; | |
371 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 } | |
380 } | |
381 } | |
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 | |
388 void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) { | |
389 internal::g_gmock_mutex.AssertHeld(); | |
390 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; | |
394 if (mockers.erase(mocker) > 0) { | |
395 // mocker was in mockers and has been just removed. | |
396 if (mockers.empty()) { | |
397 g_mock_object_registry.states().erase(it); | |
398 } | |
399 return; | |
400 } | |
401 } | |
402 } | |
403 | |
404 // Clears all ON_CALL()s set on the given mock object. | |
405 // L >= g_gmock_mutex | |
406 void Mock::ClearDefaultActionsLocked(void* mock_obj) { | |
407 internal::g_gmock_mutex.AssertHeld(); | |
408 | |
409 if (g_mock_object_registry.states().count(mock_obj) == 0) { | |
410 // 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. | |
416 FunctionMockers& mockers = | |
417 g_mock_object_registry.states()[mock_obj].function_mockers; | |
418 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 | |
427 Expectation::Expectation() {} | |
428 | |
429 Expectation::Expectation( | |
430 const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base) | |
431 : expectation_base_(an_expectation_base) {} | |
432 | |
433 Expectation::~Expectation() {} | |
434 | |
435 // Adds an expectation to a sequence. | |
436 void Sequence::AddExpectation(const Expectation& expectation) const { | |
437 if (*last_expectation_ != expectation) { | |
438 if (last_expectation_->expectation_base() != NULL) { | |
439 expectation.expectation_base()->immediate_prerequisites_ | |
440 += *last_expectation_; | |
441 } | |
442 *last_expectation_ = expectation; | |
443 } | |
444 } | |
445 | |
446 // Creates the implicit sequence if there isn't one. | |
447 InSequence::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. | |
458 InSequence::~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 | |
OLD | NEW |