Skip to content

Commit

Permalink
Issue sebastianbergmann#261: Fix duplicate callback parameter constra…
Browse files Browse the repository at this point in the history
…int evaluation

* Add test to reproduce Issue sebastianbergmann#261
* Fix Issue sebastianbergmann#261
  • Loading branch information
Vinai committed Jun 11, 2016
1 parent 73bb670 commit 944cd09
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
28 changes: 26 additions & 2 deletions src/Framework/MockObject/Matcher/Parameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ class PHPUnit_Framework_MockObject_Matcher_Parameters extends PHPUnit_Framework_
*/
protected $invocation;

/**
* @var PHPUnit_Framework_ExpectationFailedException
*/
private $parameterVerificationResult;

/**
* @param array $parameters
*/
Expand Down Expand Up @@ -71,8 +76,11 @@ public function toString()
public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
{
$this->invocation = $invocation;

return $this->verify();
try {
return $this->parameterVerificationResult = $this->verify();
} catch (PHPUnit_Framework_ExpectationFailedException $e) {
throw $this->parameterVerificationResult = $e;
}
}

/**
Expand All @@ -90,6 +98,10 @@ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
*/
public function verify()
{
if (isset($this->parameterVerificationResult)) {
return $this->guardAgainstDuplicateEvaluationOfParameterConstraints();
}

if ($this->invocation === null) {
throw new PHPUnit_Framework_ExpectationFailedException(
'Mocked method does not exist.'
Expand Down Expand Up @@ -127,4 +139,16 @@ public function verify()

return true;
}

/**
* @return bool
* @throws PHPUnit_Framework_ExpectationFailedException
*/
private function guardAgainstDuplicateEvaluationOfParameterConstraints()
{
if ($this->parameterVerificationResult instanceof Exception) {
throw $this->parameterVerificationResult;
}
return (bool) $this->parameterVerificationResult;
}
}
16 changes: 16 additions & 0 deletions tests/MockObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1017,4 +1017,20 @@ public function traversableProvider()
[['\Iterator','\Traversable']]
];
}

public function testParameterCallbackConstraintOnlyEvaluatedOnce()
{
$mock = $this->getMockBuilder(Foo::class)->setMethods(['bar'])->getMock();
$expectedNumberOfCalls = 1;
$callCount = 0;

$mock->expects($this->exactly($expectedNumberOfCalls))->method('bar')
->with($this->callback(function ($argument) use (&$callCount) {
return $argument === 'call_' . $callCount++;
}));

for ($i = 0; $i < $expectedNumberOfCalls; $i++) {
$mock->bar('call_' . $i);
}
}
}

0 comments on commit 944cd09

Please sign in to comment.