%PDF- %PDF-
Direktori : /var/www/html/car_rent/vendor/phpspec/phpspec/src/PhpSpec/Matcher/ |
Current File : /var/www/html/car_rent/vendor/phpspec/phpspec/src/PhpSpec/Matcher/ThrowMatcher.php |
<?php /* * This file is part of PhpSpec, A php toolset to drive emergent * design by specification. * * (c) Marcello Duarte <marcello.duarte@gmail.com> * (c) Konstantin Kudryashov <ever.zet@gmail.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PhpSpec\Matcher; use PhpSpec\Formatter\Presenter\PresenterInterface; use PhpSpec\Wrapper\Unwrapper; use PhpSpec\Wrapper\DelayedCall; use PhpSpec\Factory\ReflectionFactory; use PhpSpec\Exception\Example\MatcherException; use PhpSpec\Exception\Example\FailureException; use PhpSpec\Exception\Example\NotEqualException; use PhpSpec\Exception\Fracture\MethodNotFoundException; class ThrowMatcher implements MatcherInterface { /** * @var array */ private static $ignoredProperties = array('file', 'line', 'string', 'trace', 'previous'); /** * @var Unwrapper */ private $unwrapper; /** * @var PresenterInterface */ private $presenter; /** * @var ReflectionFactory */ private $factory; /** * @param Unwrapper $unwrapper * @param PresenterInterface $presenter * @param ReflectionFactory|null $factory */ public function __construct(Unwrapper $unwrapper, PresenterInterface $presenter, ReflectionFactory $factory = null) { $this->unwrapper = $unwrapper; $this->presenter = $presenter; $this->factory = $factory ?: new ReflectionFactory(); } /** * @param string $name * @param mixed $subject * @param array $arguments * * @return bool */ public function supports($name, $subject, array $arguments) { return 'throw' === $name; } /** * @param string $name * @param mixed $subject * @param array $arguments * * @return DelayedCall */ public function positiveMatch($name, $subject, array $arguments) { return $this->getDelayedCall(array($this, 'verifyPositive'), $subject, $arguments); } /** * @param string $name * @param mixed $subject * @param array $arguments * * @return DelayedCall */ public function negativeMatch($name, $subject, array $arguments) { return $this->getDelayedCall(array($this, 'verifyNegative'), $subject, $arguments); } /** * @param callable $callable * @param array $arguments * @param null|object|string $exception * * @throws \PhpSpec\Exception\Example\FailureException * @throws \PhpSpec\Exception\Example\NotEqualException */ public function verifyPositive($callable, array $arguments, $exception = null) { $exceptionThrown = null; try { call_user_func_array($callable, $arguments); } catch (\Exception $e) { $exceptionThrown = $e; } catch (\Throwable $e) { $exceptionThrown = $e; } if (!$exceptionThrown) { throw new FailureException('Expected to get exception / throwable, none got.'); } if (null === $exception) { return; } if (!$exceptionThrown instanceof $exception) { throw new FailureException( sprintf( 'Expected exception of class %s, but got %s.', $this->presenter->presentValue($exception), $this->presenter->presentValue($exceptionThrown) ) ); } if (is_object($exception)) { $exceptionRefl = $this->factory->create($exception); foreach ($exceptionRefl->getProperties() as $property) { if (in_array($property->getName(), self::$ignoredProperties, true)) { continue; } $property->setAccessible(true); $expected = $property->getValue($exception); $actual = $property->getValue($exceptionThrown); if (null !== $expected && $actual !== $expected) { throw new NotEqualException( sprintf( 'Expected exception `%s` to be %s, but it is %s.', $property->getName(), $this->presenter->presentValue($expected), $this->presenter->presentValue($actual) ), $expected, $actual ); } } } } /** * @param callable $callable * @param array $arguments * @param string|null|object $exception * * @throws \PhpSpec\Exception\Example\FailureException */ public function verifyNegative($callable, array $arguments, $exception = null) { $exceptionThrown = null; try { call_user_func_array($callable, $arguments); } catch (\Exception $e) { $exceptionThrown = $e; } catch (\Throwable $e) { $exceptionThrown = $e; } if ($exceptionThrown && null === $exception) { throw new FailureException( sprintf( 'Expected to not throw any exceptions, but got %s.', $this->presenter->presentValue($exceptionThrown) ) ); } if ($exceptionThrown && $exceptionThrown instanceof $exception) { $invalidProperties = array(); if (is_object($exception)) { $exceptionRefl = $this->factory->create($exception); foreach ($exceptionRefl->getProperties() as $property) { if (in_array($property->getName(), self::$ignoredProperties, true)) { continue; } $property->setAccessible(true); $expected = $property->getValue($exception); $actual = $property->getValue($exceptionThrown); if (null !== $expected && $actual === $expected) { $invalidProperties[] = sprintf( ' `%s`=%s', $property->getName(), $this->presenter->presentValue($expected) ); } } } $withProperties = ''; if (count($invalidProperties) > 0) { $withProperties = sprintf( ' with'.PHP_EOL.'%s,'.PHP_EOL, implode(",\n", $invalidProperties) ); } throw new FailureException( sprintf( 'Expected to not throw %s exception%s but got it.', $this->presenter->presentValue($exception), $withProperties ) ); } } /** * @return int */ public function getPriority() { return 1; } /** * @param callable $check * @param mixed $subject * @param array $arguments * * @return DelayedCall */ private function getDelayedCall($check, $subject, array $arguments) { $exception = $this->getException($arguments); $unwrapper = $this->unwrapper; return new DelayedCall( function ($method, $arguments) use ($check, $subject, $exception, $unwrapper) { $arguments = $unwrapper->unwrapAll($arguments); $methodName = $arguments[0]; $arguments = isset($arguments[1]) ? $arguments[1] : array(); $callable = array($subject, $methodName); list($class, $methodName) = array($subject, $methodName); if (!method_exists($class, $methodName) && !method_exists($class, '__call')) { throw new MethodNotFoundException( sprintf('Method %s::%s not found.', get_class($class), $methodName), $class, $methodName, $arguments ); } return call_user_func($check, $callable, $arguments, $exception); } ); } /** * @param array $arguments * * @return null|string * @throws \PhpSpec\Exception\Example\MatcherException */ private function getException(array $arguments) { if (0 === count($arguments)) { return null; } if (is_string($arguments[0])) { return $arguments[0]; } if (is_object($arguments[0])) { if ($arguments[0] instanceof \Throwable) { return $arguments[0]; } elseif ($arguments[0] instanceof \Exception) { return $arguments[0]; } } throw new MatcherException( sprintf( "Wrong argument provided in throw matcher.\n". "Fully qualified classname or exception instance expected,\n". "Got %s.", $this->presenter->presentValue($arguments[0]) ) ); } }