ObjectProphecy.php
Namespace
Prophecy\ProphecyFile
-
vendor/
phpspec/ prophecy/ src/ Prophecy/ Prophecy/ ObjectProphecy.php
View source
<?php
/*
* This file is part of the Prophecy.
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
* Marcello Duarte <marcello.duarte@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Prophecy\Prophecy;
use Prophecy\Comparator\FactoryProvider;
use SebastianBergmann\Comparator\ComparisonFailure;
use SebastianBergmann\Comparator\Factory as ComparatorFactory;
use Prophecy\Call\Call;
use Prophecy\Doubler\LazyDouble;
use Prophecy\Argument\ArgumentsWildcard;
use Prophecy\Call\CallCenter;
use Prophecy\Exception\Prophecy\ObjectProphecyException;
use Prophecy\Exception\Prophecy\MethodProphecyException;
use Prophecy\Exception\Prediction\AggregateException;
use Prophecy\Exception\Prediction\PredictionException;
/**
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*
* @template-covariant T of object
* @template-implements ProphecyInterface<T>
*/
class ObjectProphecy implements ProphecyInterface {
/**
* @var LazyDouble<T>
*/
private $lazyDouble;
private $callCenter;
private $revealer;
private $comparatorFactory;
/**
* @var array<string, list<MethodProphecy>>
*/
private $methodProphecies = array();
/**
* @param LazyDouble<T> $lazyDouble
*/
public function __construct(LazyDouble $lazyDouble, ?CallCenter $callCenter = null, ?RevealerInterface $revealer = null, ?ComparatorFactory $comparatorFactory = null) {
$this->lazyDouble = $lazyDouble;
$this->callCenter = $callCenter ?: new CallCenter();
$this->revealer = $revealer ?: new Revealer();
$this->comparatorFactory = $comparatorFactory ?: FactoryProvider::getInstance();
}
/**
* Forces double to extend specific class.
*
* @param string $class
*
* @return $this
*
* @template U of object
* @phpstan-param class-string<U> $class
* @phpstan-this-out static<T&U>
*/
public function willExtend($class) {
$this->lazyDouble
->setParentClass($class);
return $this;
}
/**
* Forces double to implement specific interface.
*
* @param string $interface
*
* @return $this
*
* @template U of object
* @phpstan-param class-string<U> $interface
* @phpstan-this-out static<T&U>
*/
public function willImplement($interface) {
$this->lazyDouble
->addInterface($interface);
return $this;
}
/**
* Sets constructor arguments.
*
* @param array<mixed> $arguments
*
* @return $this
*/
public function willBeConstructedWith(?array $arguments = null) {
$this->lazyDouble
->setArguments($arguments);
return $this;
}
/**
* Reveals double.
*
* @return object
*
* @throws \Prophecy\Exception\Prophecy\ObjectProphecyException If double doesn't implement needed interface
*
* @phpstan-return T
*/
public function reveal() {
$double = $this->lazyDouble
->getInstance();
if (!$double instanceof ProphecySubjectInterface) {
throw new ObjectProphecyException("Generated double must implement ProphecySubjectInterface, but it does not.\n" . 'It seems you have wrongly configured doubler without required ClassPatch.', $this);
}
$double->setProphecy($this);
return $double;
}
/**
* Adds method prophecy to object prophecy.
*
* @param MethodProphecy $methodProphecy
*
* @return void
*/
public function addMethodProphecy(MethodProphecy $methodProphecy) {
$methodName = strtolower($methodProphecy->getMethodName());
if (!isset($this->methodProphecies[$methodName])) {
$this->methodProphecies[$methodName] = array();
}
$this->methodProphecies[$methodName][] = $methodProphecy;
}
/**
* Returns either all or related to single method prophecies.
*
* @param null|string $methodName
*
* @return MethodProphecy[]|array<string, MethodProphecy[]>
*
* @phpstan-return ($methodName is string ? list<MethodProphecy> : array<string, list<MethodProphecy>>)
*/
public function getMethodProphecies($methodName = null) {
if (null === $methodName) {
return $this->methodProphecies;
}
$methodName = strtolower($methodName);
if (!isset($this->methodProphecies[$methodName])) {
return array();
}
return $this->methodProphecies[$methodName];
}
/**
* Makes specific method call.
*
* @param string $methodName
* @param array<mixed> $arguments
*
* @return mixed
*/
public function makeProphecyMethodCall($methodName, array $arguments) {
$arguments = $this->revealer
->reveal($arguments);
\assert(\is_array($arguments));
$return = $this->callCenter
->makeCall($this, $methodName, $arguments);
return $this->revealer
->reveal($return);
}
/**
* Finds calls by method name & arguments wildcard.
*
* @param string $methodName
* @param ArgumentsWildcard $wildcard
*
* @return list<Call>
*/
public function findProphecyMethodCalls($methodName, ArgumentsWildcard $wildcard) {
return $this->callCenter
->findCalls($methodName, $wildcard);
}
/**
* Checks that registered method predictions do not fail.
*
* @return void
*
* @throws \Prophecy\Exception\Prediction\AggregateException If any of registered predictions fail
* @throws \Prophecy\Exception\Call\UnexpectedCallException
*/
public function checkProphecyMethodsPredictions() {
$exception = new AggregateException(sprintf("%s:\n", get_class($this->reveal())));
$exception->setObjectProphecy($this);
$this->callCenter
->checkUnexpectedCalls();
foreach ($this->methodProphecies as $prophecies) {
foreach ($prophecies as $prophecy) {
try {
$prophecy->checkPrediction();
} catch (PredictionException $e) {
$exception->append($e);
}
}
}
if (count($exception->getExceptions())) {
throw $exception;
}
}
/**
* Creates new method prophecy using specified method name and arguments.
*
* @param string $methodName
* @param array<mixed> $arguments
*
* @return MethodProphecy
*/
public function __call($methodName, array $arguments) {
$arguments = $this->revealer
->reveal($arguments);
\assert(\is_array($arguments));
$arguments = new ArgumentsWildcard($arguments);
foreach ($this->getMethodProphecies($methodName) as $prophecy) {
$argumentsWildcard = $prophecy->getArgumentsWildcard();
$comparator = $this->comparatorFactory
->getComparatorFor($argumentsWildcard, $arguments);
try {
$comparator->assertEquals($argumentsWildcard, $arguments);
return $prophecy;
} catch (ComparisonFailure $failure) {
}
}
return new MethodProphecy($this, $methodName, $arguments);
}
/**
* Tries to get property value from double.
*
* @param string $name
*
* @return mixed
*/
public function __get($name) {
return $this->reveal()->{$name};
}
/**
* Tries to set property value to double.
*
* @param string $name
* @param mixed $value
*
* @return void
*/
public function __set($name, $value) {
$this->reveal()->{$name} = $this->revealer
->reveal($value);
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
ObjectProphecy | @author Konstantin Kudryashov <ever.zet@gmail.com> |