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 <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 |
OLD | NEW |