Allows a mock object to delete itself in an action. By Simon Bowden.
This commit is contained in:
		@@ -1426,6 +1426,7 @@ class InvokeWithHelper {
 | 
				
			|||||||
    bool is_excessive = false;
 | 
					    bool is_excessive = false;
 | 
				
			||||||
    ::std::stringstream ss;
 | 
					    ::std::stringstream ss;
 | 
				
			||||||
    ::std::stringstream why;
 | 
					    ::std::stringstream why;
 | 
				
			||||||
 | 
					    ::std::stringstream loc;
 | 
				
			||||||
    Action<F> action;
 | 
					    Action<F> action;
 | 
				
			||||||
    Expectation<F>* exp;
 | 
					    Expectation<F>* exp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1435,6 +1436,11 @@ class InvokeWithHelper {
 | 
				
			|||||||
        args, &exp, &action, &is_excessive, &ss, &why);
 | 
					        args, &exp, &action, &is_excessive, &ss, &why);
 | 
				
			||||||
    ss << "    Function call: " << mocker->Name();
 | 
					    ss << "    Function call: " << mocker->Name();
 | 
				
			||||||
    UniversalPrinter<ArgumentTuple>::Print(args, &ss);
 | 
					    UniversalPrinter<ArgumentTuple>::Print(args, &ss);
 | 
				
			||||||
 | 
					    // In case the action deletes a piece of the expectation, we
 | 
				
			||||||
 | 
					    // generate the message beforehand.
 | 
				
			||||||
 | 
					    if (found && !is_excessive) {
 | 
				
			||||||
 | 
					      exp->DescribeLocationTo(&loc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    Result result = action.IsDoDefault() ?
 | 
					    Result result = action.IsDoDefault() ?
 | 
				
			||||||
        mocker->PerformDefaultAction(args, ss.str())
 | 
					        mocker->PerformDefaultAction(args, ss.str())
 | 
				
			||||||
        : action.Perform(args);
 | 
					        : action.Perform(args);
 | 
				
			||||||
@@ -1449,8 +1455,6 @@ class InvokeWithHelper {
 | 
				
			|||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        // We had an expected call and the matching expectation is
 | 
					        // We had an expected call and the matching expectation is
 | 
				
			||||||
        // described in ss.
 | 
					        // described in ss.
 | 
				
			||||||
        ::std::stringstream loc;
 | 
					 | 
				
			||||||
        exp->DescribeLocationTo(&loc);
 | 
					 | 
				
			||||||
        Log(INFO, loc.str() + ss.str(), 3);
 | 
					        Log(INFO, loc.str() + ss.str(), 3);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@@ -1494,6 +1498,7 @@ class InvokeWithHelper<void, F> {
 | 
				
			|||||||
    bool is_excessive = false;
 | 
					    bool is_excessive = false;
 | 
				
			||||||
    ::std::stringstream ss;
 | 
					    ::std::stringstream ss;
 | 
				
			||||||
    ::std::stringstream why;
 | 
					    ::std::stringstream why;
 | 
				
			||||||
 | 
					    ::std::stringstream loc;
 | 
				
			||||||
    Action<F> action;
 | 
					    Action<F> action;
 | 
				
			||||||
    Expectation<F>* exp;
 | 
					    Expectation<F>* exp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1504,6 +1509,11 @@ class InvokeWithHelper<void, F> {
 | 
				
			|||||||
    ss << "    Function call: " << mocker->Name();
 | 
					    ss << "    Function call: " << mocker->Name();
 | 
				
			||||||
    UniversalPrinter<ArgumentTuple>::Print(args, &ss);
 | 
					    UniversalPrinter<ArgumentTuple>::Print(args, &ss);
 | 
				
			||||||
    ss << "\n" << why.str();
 | 
					    ss << "\n" << why.str();
 | 
				
			||||||
 | 
					    // In case the action deletes a piece of the expectation, we
 | 
				
			||||||
 | 
					    // generate the message beforehand.
 | 
				
			||||||
 | 
					    if (found && !is_excessive) {
 | 
				
			||||||
 | 
					      exp->DescribeLocationTo(&loc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (action.IsDoDefault()) {
 | 
					    if (action.IsDoDefault()) {
 | 
				
			||||||
      mocker->PerformDefaultAction(args, ss.str());
 | 
					      mocker->PerformDefaultAction(args, ss.str());
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@@ -1518,8 +1528,6 @@ class InvokeWithHelper<void, F> {
 | 
				
			|||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        // We had an expected call and the matching expectation is
 | 
					        // We had an expected call and the matching expectation is
 | 
				
			||||||
        // described in ss.
 | 
					        // described in ss.
 | 
				
			||||||
        ::std::stringstream loc;
 | 
					 | 
				
			||||||
        exp->DescribeLocationTo(&loc);
 | 
					 | 
				
			||||||
        Log(INFO, loc.str() + ss.str(), 3);
 | 
					        Log(INFO, loc.str() + ss.str(), 3);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1304,7 +1304,24 @@ TEST(DeletingMockEarlyTest, Success2) {
 | 
				
			|||||||
  delete b2;
 | 
					  delete b2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that calls that violates the original spec yield failures.
 | 
					// Tests that it's OK to delete a mock object itself in its action.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ACTION_P(Delete, ptr) { delete ptr; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(DeletingMockEarlyTest, CanDeleteSelfInActionReturningVoid) {
 | 
				
			||||||
 | 
					  MockA* const a = new MockA;
 | 
				
			||||||
 | 
					  EXPECT_CALL(*a, DoA(_)).WillOnce(Delete(a));
 | 
				
			||||||
 | 
					  a->DoA(42);  // This will cause a to be deleted.
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(DeletingMockEarlyTest, CanDeleteSelfInActionReturningValue) {
 | 
				
			||||||
 | 
					  MockA* const a = new MockA;
 | 
				
			||||||
 | 
					  EXPECT_CALL(*a, ReturnResult(_))
 | 
				
			||||||
 | 
					      .WillOnce(DoAll(Delete(a), Return(Result())));
 | 
				
			||||||
 | 
					  a->ReturnResult(42);  // This will cause a to be deleted.
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tests that calls that violate the original spec yield failures.
 | 
				
			||||||
TEST(DeletingMockEarlyTest, Failure1) {
 | 
					TEST(DeletingMockEarlyTest, Failure1) {
 | 
				
			||||||
  MockB* const b1 = new MockB;
 | 
					  MockB* const b1 = new MockB;
 | 
				
			||||||
  MockA* const a = new MockA;
 | 
					  MockA* const a = new MockA;
 | 
				
			||||||
@@ -1330,7 +1347,7 @@ TEST(DeletingMockEarlyTest, Failure1) {
 | 
				
			|||||||
  delete b2;
 | 
					  delete b2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that calls that violates the original spec yield failures.
 | 
					// Tests that calls that violate the original spec yield failures.
 | 
				
			||||||
TEST(DeletingMockEarlyTest, Failure2) {
 | 
					TEST(DeletingMockEarlyTest, Failure2) {
 | 
				
			||||||
  MockB* const b1 = new MockB;
 | 
					  MockB* const b1 = new MockB;
 | 
				
			||||||
  MockA* const a = new MockA;
 | 
					  MockA* const a = new MockA;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user