Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: testing/gmock/src/gmock-spec-builders.cc

Issue 115846: Retry to checkin a version of gmock, modified to use our boost_tuple in VS2005. (Closed)
Patch Set: Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « testing/gmock/src/gmock-printers.cc ('k') | testing/gmock/src/gmock_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 <gmock/gmock.h>
44 #include <gtest/gtest.h>
45
46 #if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
47 #include <unistd.h> // NOLINT
48 #endif
49
50 namespace testing {
51 namespace internal {
52
53 // Protects the mock object registry (in class Mock), all function
54 // mockers, and all expectations.
55 Mutex g_gmock_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
56
57 // Constructs an ExpectationBase object.
58 ExpectationBase::ExpectationBase(const char* file, int line)
59 : file_(file),
60 line_(line),
61 cardinality_specified_(false),
62 cardinality_(Exactly(1)),
63 call_count_(0),
64 retired_(false) {
65 }
66
67 // Destructs an ExpectationBase object.
68 ExpectationBase::~ExpectationBase() {}
69
70 // Explicitly specifies the cardinality of this expectation. Used by
71 // the subclasses to implement the .Times() clause.
72 void ExpectationBase::SpecifyCardinality(const Cardinality& cardinality) {
73 cardinality_specified_ = true;
74 cardinality_ = cardinality;
75 }
76
77 // Retires all pre-requisites of this expectation.
78 void ExpectationBase::RetireAllPreRequisites() {
79 if (is_retired()) {
80 // We can take this short-cut as we never retire an expectation
81 // until we have retired all its pre-requisites.
82 return;
83 }
84
85 for (ExpectationBaseSet::const_iterator it =
86 immediate_prerequisites_.begin();
87 it != immediate_prerequisites_.end();
88 ++it) {
89 ExpectationBase* const prerequisite = (*it).get();
90 if (!prerequisite->is_retired()) {
91 prerequisite->RetireAllPreRequisites();
92 prerequisite->Retire();
93 }
94 }
95 }
96
97 // Returns true iff all pre-requisites of this expectation have been
98 // satisfied.
99 // L >= g_gmock_mutex
100 bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
101 g_gmock_mutex.AssertHeld();
102 for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
103 it != immediate_prerequisites_.end(); ++it) {
104 if (!(*it)->IsSatisfied() ||
105 !(*it)->AllPrerequisitesAreSatisfied())
106 return false;
107 }
108 return true;
109 }
110
111 // Adds unsatisfied pre-requisites of this expectation to 'result'.
112 // L >= g_gmock_mutex
113 void ExpectationBase::FindUnsatisfiedPrerequisites(
114 ExpectationBaseSet* result) const {
115 g_gmock_mutex.AssertHeld();
116 for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
117 it != immediate_prerequisites_.end(); ++it) {
118 if ((*it)->IsSatisfied()) {
119 // If *it is satisfied and has a call count of 0, some of its
120 // pre-requisites may not be satisfied yet.
121 if ((*it)->call_count_ == 0) {
122 (*it)->FindUnsatisfiedPrerequisites(result);
123 }
124 } else {
125 // Now that we know *it is unsatisfied, we are not so interested
126 // in whether its pre-requisites are satisfied. Therefore we
127 // don't recursively call FindUnsatisfiedPrerequisites() here.
128 result->insert(*it);
129 }
130 }
131 }
132
133 // Points to the implicit sequence introduced by a living InSequence
134 // object (if any) in the current thread or NULL.
135 ThreadLocal<Sequence*> g_gmock_implicit_sequence;
136
137 // Reports an uninteresting call (whose description is in msg) in the
138 // manner specified by 'reaction'.
139 void ReportUninterestingCall(CallReaction reaction, const string& msg) {
140 switch (reaction) {
141 case ALLOW:
142 Log(INFO, msg, 4);
143 break;
144 case WARN:
145 Log(WARNING, msg, 4);
146 break;
147 default: // FAIL
148 Expect(false, NULL, -1, msg);
149 }
150 }
151
152 } // namespace internal
153
154 // Class Mock.
155
156 namespace {
157
158 typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
159
160 // The current state of a mock object. Such information is needed for
161 // detecting leaked mock objects and explicitly verifying a mock's
162 // expectations.
163 struct MockObjectState {
164 MockObjectState()
165 : first_used_file(NULL), first_used_line(-1), leakable(false) {}
166
167 // Where in the source file an ON_CALL or EXPECT_CALL is first
168 // invoked on this mock object.
169 const char* first_used_file;
170 int first_used_line;
171 ::std::string first_used_test_case;
172 ::std::string first_used_test;
173 bool leakable; // true iff it's OK to leak the object.
174 FunctionMockers function_mockers; // All registered methods of the object.
175 };
176
177 // A global registry holding the state of all mock objects that are
178 // alive. A mock object is added to this registry the first time
179 // Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
180 // is removed from the registry in the mock object's destructor.
181 class MockObjectRegistry {
182 public:
183 // Maps a mock object (identified by its address) to its state.
184 typedef std::map<const void*, MockObjectState> StateMap;
185
186 // This destructor will be called when a program exits, after all
187 // tests in it have been run. By then, there should be no mock
188 // object alive. Therefore we report any living object as test
189 // failure, unless the user explicitly asked us to ignore it.
190 ~MockObjectRegistry() {
191 using ::std::cout;
192
193 if (!GMOCK_FLAG(catch_leaked_mocks))
194 return;
195
196 int leaked_count = 0;
197 for (StateMap::const_iterator it = states_.begin(); it != states_.end();
198 ++it) {
199 if (it->second.leakable) // The user said it's fine to leak this object.
200 continue;
201
202 // TODO(wan@google.com): Print the type of the leaked object.
203 // This can help the user identify the leaked object.
204 cout << "\n";
205 const MockObjectState& state = it->second;
206 internal::FormatFileLocation(
207 state.first_used_file, state.first_used_line, &cout);
208 cout << " ERROR: this mock object";
209 if (state.first_used_test != "") {
210 cout << " (used in test " << state.first_used_test_case << "."
211 << state.first_used_test << ")";
212 }
213 cout << " should be deleted but never is. Its address is @"
214 << it->first << ".";
215 leaked_count++;
216 }
217 if (leaked_count > 0) {
218 cout << "\nERROR: " << leaked_count
219 << " leaked mock " << (leaked_count == 1 ? "object" : "objects")
220 << " found at program exit.\n";
221 cout.flush();
222 ::std::cerr.flush();
223 // RUN_ALL_TESTS() has already returned when this destructor is
224 // called. Therefore we cannot use the normal Google Test
225 // failure reporting mechanism.
226 _exit(1); // We cannot call exit() as it is not reentrant and
227 // may already have been called.
228 }
229 }
230
231 StateMap& states() { return states_; }
232 private:
233 StateMap states_;
234 };
235
236 // Protected by g_gmock_mutex.
237 MockObjectRegistry g_mock_object_registry;
238
239 // Maps a mock object to the reaction Google Mock should have when an
240 // uninteresting method is called. Protected by g_gmock_mutex.
241 std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
242
243 // Sets the reaction Google Mock should have when an uninteresting
244 // method of the given mock object is called.
245 // L < g_gmock_mutex
246 void SetReactionOnUninterestingCalls(const void* mock_obj,
247 internal::CallReaction reaction) {
248 internal::MutexLock l(&internal::g_gmock_mutex);
249 g_uninteresting_call_reaction[mock_obj] = reaction;
250 }
251
252 } // namespace
253
254 // Tells Google Mock to allow uninteresting calls on the given mock
255 // object.
256 // L < g_gmock_mutex
257 void Mock::AllowUninterestingCalls(const void* mock_obj) {
258 SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW);
259 }
260
261 // Tells Google Mock to warn the user about uninteresting calls on the
262 // given mock object.
263 // L < g_gmock_mutex
264 void Mock::WarnUninterestingCalls(const void* mock_obj) {
265 SetReactionOnUninterestingCalls(mock_obj, internal::WARN);
266 }
267
268 // Tells Google Mock to fail uninteresting calls on the given mock
269 // object.
270 // L < g_gmock_mutex
271 void Mock::FailUninterestingCalls(const void* mock_obj) {
272 SetReactionOnUninterestingCalls(mock_obj, internal::FAIL);
273 }
274
275 // Tells Google Mock the given mock object is being destroyed and its
276 // entry in the call-reaction table should be removed.
277 // L < g_gmock_mutex
278 void Mock::UnregisterCallReaction(const void* mock_obj) {
279 internal::MutexLock l(&internal::g_gmock_mutex);
280 g_uninteresting_call_reaction.erase(mock_obj);
281 }
282
283 // Returns the reaction Google Mock will have on uninteresting calls
284 // made on the given mock object.
285 // L < g_gmock_mutex
286 internal::CallReaction Mock::GetReactionOnUninterestingCalls(
287 const void* mock_obj) {
288 internal::MutexLock l(&internal::g_gmock_mutex);
289 return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
290 internal::WARN : g_uninteresting_call_reaction[mock_obj];
291 }
292
293 // Tells Google Mock to ignore mock_obj when checking for leaked mock
294 // objects.
295 // L < g_gmock_mutex
296 void Mock::AllowLeak(const void* mock_obj) {
297 internal::MutexLock l(&internal::g_gmock_mutex);
298 g_mock_object_registry.states()[mock_obj].leakable = true;
299 }
300
301 // Verifies and clears all expectations on the given mock object. If
302 // the expectations aren't satisfied, generates one or more Google
303 // Test non-fatal failures and returns false.
304 // L < g_gmock_mutex
305 bool Mock::VerifyAndClearExpectations(void* mock_obj) {
306 internal::MutexLock l(&internal::g_gmock_mutex);
307 return VerifyAndClearExpectationsLocked(mock_obj);
308 }
309
310 // Verifies all expectations on the given mock object and clears its
311 // default actions and expectations. Returns true iff the
312 // verification was successful.
313 // L < g_gmock_mutex
314 bool Mock::VerifyAndClear(void* mock_obj) {
315 internal::MutexLock l(&internal::g_gmock_mutex);
316 ClearDefaultActionsLocked(mock_obj);
317 return VerifyAndClearExpectationsLocked(mock_obj);
318 }
319
320 // Verifies and clears all expectations on the given mock object. If
321 // the expectations aren't satisfied, generates one or more Google
322 // Test non-fatal failures and returns false.
323 // L >= g_gmock_mutex
324 bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
325 internal::g_gmock_mutex.AssertHeld();
326 if (g_mock_object_registry.states().count(mock_obj) == 0) {
327 // No EXPECT_CALL() was set on the given mock object.
328 return true;
329 }
330
331 // Verifies and clears the expectations on each mock method in the
332 // given mock object.
333 bool expectations_met = true;
334 FunctionMockers& mockers =
335 g_mock_object_registry.states()[mock_obj].function_mockers;
336 for (FunctionMockers::const_iterator it = mockers.begin();
337 it != mockers.end(); ++it) {
338 if (!(*it)->VerifyAndClearExpectationsLocked()) {
339 expectations_met = false;
340 }
341 }
342
343 // We don't clear the content of mockers, as they may still be
344 // needed by ClearDefaultActionsLocked().
345 return expectations_met;
346 }
347
348 // Registers a mock object and a mock method it owns.
349 // L < g_gmock_mutex
350 void Mock::Register(const void* mock_obj,
351 internal::UntypedFunctionMockerBase* mocker) {
352 internal::MutexLock l(&internal::g_gmock_mutex);
353 g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
354 }
355
356 // Tells Google Mock where in the source code mock_obj is used in an
357 // ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
358 // information helps the user identify which object it is.
359 // L < g_gmock_mutex
360 void Mock::RegisterUseByOnCallOrExpectCall(
361 const void* mock_obj, const char* file, int line) {
362 internal::MutexLock l(&internal::g_gmock_mutex);
363 MockObjectState& state = g_mock_object_registry.states()[mock_obj];
364 if (state.first_used_file == NULL) {
365 state.first_used_file = file;
366 state.first_used_line = line;
367 const TestInfo* const test_info =
368 UnitTest::GetInstance()->current_test_info();
369 if (test_info != NULL) {
370 // TODO(wan@google.com): record the test case name when the
371 // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
372 // TearDownTestCase().
373 state.first_used_test_case = test_info->test_case_name();
374 state.first_used_test = test_info->name();
375 }
376 }
377 }
378
379 // Unregisters a mock method; removes the owning mock object from the
380 // registry when the last mock method associated with it has been
381 // unregistered. This is called only in the destructor of
382 // FunctionMockerBase.
383 // L >= g_gmock_mutex
384 void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
385 internal::g_gmock_mutex.AssertHeld();
386 for (MockObjectRegistry::StateMap::iterator it =
387 g_mock_object_registry.states().begin();
388 it != g_mock_object_registry.states().end(); ++it) {
389 FunctionMockers& mockers = it->second.function_mockers;
390 if (mockers.erase(mocker) > 0) {
391 // mocker was in mockers and has been just removed.
392 if (mockers.empty()) {
393 g_mock_object_registry.states().erase(it);
394 }
395 return;
396 }
397 }
398 }
399
400 // Clears all ON_CALL()s set on the given mock object.
401 // L >= g_gmock_mutex
402 void Mock::ClearDefaultActionsLocked(void* mock_obj) {
403 internal::g_gmock_mutex.AssertHeld();
404
405 if (g_mock_object_registry.states().count(mock_obj) == 0) {
406 // No ON_CALL() was set on the given mock object.
407 return;
408 }
409
410 // Clears the default actions for each mock method in the given mock
411 // object.
412 FunctionMockers& mockers =
413 g_mock_object_registry.states()[mock_obj].function_mockers;
414 for (FunctionMockers::const_iterator it = mockers.begin();
415 it != mockers.end(); ++it) {
416 (*it)->ClearDefaultActionsLocked();
417 }
418
419 // We don't clear the content of mockers, as they may still be
420 // needed by VerifyAndClearExpectationsLocked().
421 }
422
423 // Adds an expectation to a sequence.
424 void Sequence::AddExpectation(
425 const internal::linked_ptr<internal::ExpectationBase>& expectation) const {
426 if (*last_expectation_ != expectation) {
427 if (*last_expectation_ != NULL) {
428 expectation->immediate_prerequisites_.insert(*last_expectation_);
429 }
430 *last_expectation_ = expectation;
431 }
432 }
433
434 // Creates the implicit sequence if there isn't one.
435 InSequence::InSequence() {
436 if (internal::g_gmock_implicit_sequence.get() == NULL) {
437 internal::g_gmock_implicit_sequence.set(new Sequence);
438 sequence_created_ = true;
439 } else {
440 sequence_created_ = false;
441 }
442 }
443
444 // Deletes the implicit sequence if it was created by the constructor
445 // of this object.
446 InSequence::~InSequence() {
447 if (sequence_created_) {
448 delete internal::g_gmock_implicit_sequence.get();
449 internal::g_gmock_implicit_sequence.set(NULL);
450 }
451 }
452
453 } // namespace testing
OLDNEW
« no previous file with comments | « testing/gmock/src/gmock-printers.cc ('k') | testing/gmock/src/gmock_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698