Skip to content

Commit

Permalink
Merge pull request #288 from jameshalsall/allow-error-instances-in-th…
Browse files Browse the repository at this point in the history
…row-promise

Allow \Error instances in ThrowPromise
  • Loading branch information
everzet committed Mar 2, 2017
2 parents 8d80f98 + cbfa71d commit 291ad67
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
44 changes: 44 additions & 0 deletions spec/Prophecy/Promise/ThrowPromiseSpec.php
Expand Up @@ -2,6 +2,7 @@

namespace spec\Prophecy\Promise;

use PhpSpec\Exception\Example\SkippingException;
use PhpSpec\ObjectBehavior;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
Expand Down Expand Up @@ -40,6 +41,49 @@ function it_throws_provided_exception(ObjectProphecy $object, MethodProphecy $me

$this->shouldThrow($exc)->duringExecute(array(), $object, $method);
}

function it_throws_error_instances(ObjectProphecy $object, MethodProphecy $method)
{
if (!class_exists('\Error')) {
throw new SkippingException('The class Error, introduced in PHP 7, does not exist');
}

$this->beConstructedWith($exc = new \Error('Error exception'));

$this->shouldThrow($exc)->duringExecute(array(), $object, $method);
}

function it_throws_errors_by_class_name()
{
if (!class_exists('\Error')) {
throw new SkippingException('The class Error, introduced in PHP 7, does not exist');
}

$this->beConstructedWith('\Error');

$this->shouldNotThrow('Prophecy\Exception\InvalidArgumentException')->duringInstantiation();
}

function it_does_not_throw_something_that_is_not_throwable_by_class_name()
{
$this->beConstructedWith('\stdClass');

$this->shouldThrow('Prophecy\Exception\InvalidArgumentException')->duringInstantiation();
}

function it_does_not_throw_something_that_is_not_throwable_by_instance()
{
$this->beConstructedWith(new \stdClass());

$this->shouldThrow('Prophecy\Exception\InvalidArgumentException')->duringInstantiation();
}

function it_throws_an_exception_by_class_name()
{
$this->beConstructedWith('\Exception');

$this->shouldNotThrow('Prophecy\Exception\InvalidArgumentException')->duringInstantiation();
}
}

class RequiredArgumentException extends \Exception
Expand Down
22 changes: 15 additions & 7 deletions src/Prophecy/Promise/ThrowPromise.php
Expand Up @@ -34,24 +34,22 @@ class ThrowPromise implements PromiseInterface
/**
* Initializes promise.
*
* @param string|\Exception $exception Exception class name or instance
* @param string|\Exception|\Throwable $exception Exception class name or instance
*
* @throws \Prophecy\Exception\InvalidArgumentException
*/
public function __construct($exception)
{
if (is_string($exception)) {
if (!class_exists($exception)
&& 'Exception' !== $exception
&& !is_subclass_of($exception, 'Exception')) {
if (!class_exists($exception) || !$this->isAValidThrowable($exception)) {
throw new InvalidArgumentException(sprintf(
'Exception class or instance expected as argument to ThrowPromise, but got %s.',
'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.',
$exception
));
}
} elseif (!$exception instanceof \Exception) {
} elseif (!$exception instanceof \Exception && !$exception instanceof \Throwable) {
throw new InvalidArgumentException(sprintf(
'Exception class or instance expected as argument to ThrowPromise, but got %s.',
'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.',
is_object($exception) ? get_class($exception) : gettype($exception)
));
}
Expand Down Expand Up @@ -88,4 +86,14 @@ public function execute(array $args, ObjectProphecy $object, MethodProphecy $met

throw $this->exception;
}

/**
* @param string $exception
*
* @return bool
*/
private function isAValidThrowable($exception)
{
return is_a($exception, 'Exception', true) || is_subclass_of($exception, 'Throwable', true);
}
}

0 comments on commit 291ad67

Please sign in to comment.