Chris@14: Chris@14: * Chris@14: * For the full copyright and license information, please view the LICENSE Chris@14: * file that was distributed with this source code. Chris@14: */ Chris@14: namespace PHPUnit\Framework\MockObject\Matcher; Chris@14: Chris@14: use PHPUnit\Framework\ExpectationFailedException; Chris@14: use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; Chris@14: Chris@14: /** Chris@14: * Invocation matcher which checks if a method has been invoked a certain amount Chris@14: * of times. Chris@14: * If the number of invocations exceeds the value it will immediately throw an Chris@14: * exception, Chris@14: * If the number is less it will later be checked in verify() and also throw an Chris@14: * exception. Chris@14: */ Chris@14: class InvokedCount extends InvokedRecorder Chris@14: { Chris@14: /** Chris@14: * @var int Chris@14: */ Chris@14: private $expectedCount; Chris@14: Chris@14: /** Chris@14: * @param int $expectedCount Chris@14: */ Chris@14: public function __construct($expectedCount) Chris@14: { Chris@14: $this->expectedCount = $expectedCount; Chris@14: } Chris@14: Chris@14: /** Chris@14: * @return bool Chris@14: */ Chris@14: public function isNever() Chris@14: { Chris@14: return $this->expectedCount === 0; Chris@14: } Chris@14: Chris@14: /** Chris@14: * @return string Chris@14: */ Chris@14: public function toString() Chris@14: { Chris@14: return 'invoked ' . $this->expectedCount . ' time(s)'; Chris@14: } Chris@14: Chris@14: /** Chris@14: * @param BaseInvocation $invocation Chris@14: * Chris@14: * @throws ExpectationFailedException Chris@14: */ Chris@14: public function invoked(BaseInvocation $invocation) Chris@14: { Chris@14: parent::invoked($invocation); Chris@14: Chris@14: $count = $this->getInvocationCount(); Chris@14: Chris@14: if ($count > $this->expectedCount) { Chris@14: $message = $invocation->toString() . ' '; Chris@14: Chris@14: switch ($this->expectedCount) { Chris@14: case 0: Chris@14: $message .= 'was not expected to be called.'; Chris@14: Chris@14: break; Chris@14: Chris@14: case 1: Chris@14: $message .= 'was not expected to be called more than once.'; Chris@14: Chris@14: break; Chris@14: Chris@14: default: Chris@14: $message .= \sprintf( Chris@14: 'was not expected to be called more than %d times.', Chris@14: $this->expectedCount Chris@14: ); Chris@14: } Chris@14: Chris@14: throw new ExpectationFailedException($message); Chris@14: } Chris@14: } Chris@14: Chris@14: /** Chris@14: * Verifies that the current expectation is valid. If everything is OK the Chris@14: * code should just return, if not it must throw an exception. Chris@14: * Chris@14: * @throws ExpectationFailedException Chris@14: */ Chris@14: public function verify() Chris@14: { Chris@14: $count = $this->getInvocationCount(); Chris@14: Chris@14: if ($count !== $this->expectedCount) { Chris@14: throw new ExpectationFailedException( Chris@14: \sprintf( Chris@14: 'Method was expected to be called %d times, ' . Chris@14: 'actually called %d times.', Chris@14: $this->expectedCount, Chris@14: $count Chris@14: ) Chris@14: ); Chris@14: } Chris@14: } Chris@14: }