First set of tests, argument unwrapping/injection

This commit is contained in:
2024-03-19 00:01:12 +01:00
parent 74960345ba
commit 35efaa1b0d
11 changed files with 870 additions and 8 deletions

View File

@ -31,7 +31,9 @@ class Command
public function call(Context $context): PromiseInterface
{
return new Promise(function (callable $resolve) use ($context) {
$resolve(call_user_func($this->handler, $context));
$args = $context->toMethodParameters($this->handler);
$resolve(call_user_func($this->handler, ...$args));
//$resolve(call_user_func($this->handler, $context));
return;
});
}

View File

@ -82,7 +82,7 @@ class CommandBus implements CommandBusInterface
case Message::MSGTYPE_RESULT: // Result from execution on client
// TODO implement me
break;
case Message::MSGTYPE_REGISTRY: // command registry actions
case Message::MSGTYPE_REGISTRY: // command registry actions
// TODO implement me
break;
default:

View File

@ -2,6 +2,10 @@
namespace NoccyLabs\React\CommandBus;
use ReflectionFunction;
use ReflectionIntersectionType;
use ReflectionNamedType;
use ReflectionUnionType;
/**
* The context contains all the data relating to calling a command. It has an
@ -37,5 +41,55 @@ class Context
{
return $this->payload[$name] ?? null;
}
public function toMethodParameters(callable $callable): array
{
$refl = new ReflectionFunction($callable);
$args = [];
// Go over the arguments
foreach ($refl->getParameters() as $parameter) {
$name = $parameter->getName();
if (!$parameter->hasType()) {
// use name
$args[] = isset($this->payload[$name])
? $this->payload[$name]
: ($parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null);
} else {
// use name and type
$type = $parameter->getType();
if ($type instanceof ReflectionNamedType && $type->isBuiltin()) {
$typeName = $type->getName();
$arg = isset($this->payload[$name])
? $this->payload[$name]
: ($parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null);
$args[] = match ($typeName) {
'string' => strval($arg),
'boolean' => boolval($arg),
'array' => (array)$arg,
'object' => (object)$arg,
'integer' => intval($arg),
'float' => floatval($arg),
default => $arg,
};
} elseif ($type instanceof ReflectionNamedType) {
$typeName = $type->getName();
switch ($typeName) {
case Context::class:
$args[] = $this;
break;
default:
$args[] = null; // FIXME how to handle this?
}
} elseif ($type instanceof ReflectionUnionType) {
$args[] = null; // FIXME how to handle this?
} elseif ($type instanceof ReflectionIntersectionType) {
$args[] = null; // FIXME how to handle this?
}
}
}
return $args;
}
}