refacto: higher order messages

This commit is contained in:
Nuno Maduro
2020-05-13 22:21:59 +02:00
parent 3b7c313c7f
commit 2d85842777
2 changed files with 30 additions and 30 deletions

View File

@ -4,11 +4,16 @@ declare(strict_types=1);
namespace Pest\Support; namespace Pest\Support;
use ReflectionClass;
use Throwable;
/** /**
* @internal * @internal
*/ */
final class HigherOrderMessage final class HigherOrderMessage
{ {
public const UNDEFINED_METHOD = 'Method %s does not exist';
/** /**
* The filename where the function was originally called. * The filename where the function was originally called.
* *
@ -57,4 +62,27 @@ final class HigherOrderMessage
$this->methodName = $methodName; $this->methodName = $methodName;
$this->arguments = $arguments; $this->arguments = $arguments;
} }
/**
* Re-throws the given `$throwable` with the good line and filename.
*
* @return mixed
*/
public function call(object $target)
{
try {
return Reflection::call($target, $this->methodName, $this->arguments);
} catch (Throwable $throwable) {
Reflection::setPropertyValue($throwable, 'file', $this->filename);
Reflection::setPropertyValue($throwable, 'line', $this->line);
if ($throwable->getMessage() === sprintf(self::UNDEFINED_METHOD, $this->methodName)) {
/** @var \ReflectionClass $reflection */
$reflection = (new ReflectionClass($target))->getParentClass();
Reflection::setPropertyValue($throwable, 'message', sprintf('Call to undefined method %s::%s()', $reflection->getName(), $this->methodName));
}
throw $throwable;
}
}
} }

View File

@ -4,16 +4,11 @@ declare(strict_types=1);
namespace Pest\Support; namespace Pest\Support;
use ReflectionClass;
use Throwable;
/** /**
* @internal * @internal
*/ */
final class HigherOrderMessageCollection final class HigherOrderMessageCollection
{ {
public const UNDEFINED_METHOD = 'Method %s does not exist';
/** /**
* @var array<int, HigherOrderMessage> * @var array<int, HigherOrderMessage>
*/ */
@ -35,7 +30,7 @@ final class HigherOrderMessageCollection
public function chain(object $target): void public function chain(object $target): void
{ {
foreach ($this->messages as $message) { foreach ($this->messages as $message) {
$target = $this->attempt($target, $message); $target = $message->call($target);
} }
} }
@ -45,30 +40,7 @@ final class HigherOrderMessageCollection
public function proxy(object $target): void public function proxy(object $target): void
{ {
foreach ($this->messages as $message) { foreach ($this->messages as $message) {
$this->attempt($target, $message); $message->call($target);
}
}
/**
* Re-throws the given `$throwable` with the good line and filename.
*
* @return mixed
*/
private function attempt(object $target, HigherOrderMessage $message)
{
try {
return Reflection::call($target, $message->methodName, $message->arguments);
} catch (Throwable $throwable) {
Reflection::setPropertyValue($throwable, 'file', $message->filename);
Reflection::setPropertyValue($throwable, 'line', $message->line);
if ($throwable->getMessage() === sprintf(self::UNDEFINED_METHOD, $message->methodName)) {
/** @var \ReflectionClass $reflection */
$reflection = (new ReflectionClass($target))->getParentClass();
Reflection::setPropertyValue($throwable, 'message', sprintf('Call to undefined method %s::%s()', $reflection->getName(), $message->methodName));
}
throw $throwable;
} }
} }
} }