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

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

Issue 6241018: Pull in gmock through DEPS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/testing
Patch Set: don't use svn mirror for now Created 9 years, 11 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 | Annotate | Revision Log
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 <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
OLDNEW
« DEPS ('K') | « testing/gmock/src/gmock-matchers.cc ('k') | testing/gmock/src/gmock_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698