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\Constraint\Constraint; Chris@14: use PHPUnit\Framework\Constraint\IsEqual; Chris@14: use PHPUnit\Framework\ExpectationFailedException; Chris@14: use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; Chris@14: Chris@14: /** Chris@14: * Invocation matcher which looks for sets of specific parameters in the invocations. Chris@14: * Chris@14: * Checks the parameters of the incoming invocations, the parameter list is Chris@14: * checked against the defined constraints in $parameters. If the constraint Chris@14: * is met it will return true in matches(). Chris@14: * Chris@14: * It takes a list of match groups and and increases a call index after each invocation. Chris@14: * So the first invocation uses the first group of constraints, the second the next and so on. Chris@14: */ Chris@14: class ConsecutiveParameters extends StatelessInvocation Chris@14: { Chris@14: /** Chris@14: * @var array Chris@14: */ Chris@14: private $parameterGroups = []; Chris@14: Chris@14: /** Chris@14: * @var array Chris@14: */ Chris@14: private $invocations = []; Chris@14: Chris@14: /** Chris@14: * @param array $parameterGroups Chris@14: * Chris@14: * @throws \PHPUnit\Framework\Exception Chris@14: */ Chris@14: public function __construct(array $parameterGroups) Chris@14: { Chris@14: foreach ($parameterGroups as $index => $parameters) { Chris@14: foreach ($parameters as $parameter) { Chris@14: if (!$parameter instanceof Constraint) { Chris@14: $parameter = new IsEqual($parameter); Chris@14: } Chris@14: Chris@14: $this->parameterGroups[$index][] = $parameter; Chris@14: } Chris@14: } Chris@14: } Chris@14: Chris@14: /** Chris@14: * @return string Chris@14: */ Chris@14: public function toString() Chris@14: { Chris@14: return 'with consecutive parameters'; Chris@14: } Chris@14: Chris@14: /** Chris@14: * @param BaseInvocation $invocation Chris@14: * Chris@14: * @return bool Chris@14: * Chris@14: * @throws \PHPUnit\Framework\ExpectationFailedException Chris@14: */ Chris@14: public function matches(BaseInvocation $invocation) Chris@14: { Chris@14: $this->invocations[] = $invocation; Chris@14: $callIndex = \count($this->invocations) - 1; Chris@14: Chris@14: $this->verifyInvocation($invocation, $callIndex); Chris@14: Chris@14: return false; Chris@14: } Chris@14: Chris@14: public function verify() Chris@14: { Chris@14: foreach ($this->invocations as $callIndex => $invocation) { Chris@14: $this->verifyInvocation($invocation, $callIndex); Chris@14: } Chris@14: } Chris@14: Chris@14: /** Chris@14: * Verify a single invocation Chris@14: * Chris@14: * @param BaseInvocation $invocation Chris@14: * @param int $callIndex Chris@14: * Chris@14: * @throws ExpectationFailedException Chris@14: */ Chris@14: private function verifyInvocation(BaseInvocation $invocation, $callIndex) Chris@14: { Chris@14: if (isset($this->parameterGroups[$callIndex])) { Chris@14: $parameters = $this->parameterGroups[$callIndex]; Chris@14: } else { Chris@14: // no parameter assertion for this call index Chris@14: return; Chris@14: } Chris@14: Chris@14: if ($invocation === null) { Chris@14: throw new ExpectationFailedException( Chris@14: 'Mocked method does not exist.' Chris@14: ); Chris@14: } Chris@14: Chris@14: if (\count($invocation->getParameters()) < \count($parameters)) { Chris@14: throw new ExpectationFailedException( Chris@14: \sprintf( Chris@14: 'Parameter count for invocation %s is too low.', Chris@14: $invocation->toString() Chris@14: ) Chris@14: ); Chris@14: } Chris@14: Chris@14: foreach ($parameters as $i => $parameter) { Chris@14: $parameter->evaluate( Chris@14: $invocation->getParameters()[$i], Chris@14: \sprintf( Chris@14: 'Parameter %s for invocation #%d %s does not match expected ' . Chris@14: 'value.', Chris@14: $i, Chris@14: $callIndex, Chris@14: $invocation->toString() Chris@14: ) Chris@14: ); Chris@14: } Chris@14: } Chris@14: }