From dfdfeabc5ac9e841e8546f146d97fdedc7fdc027 Mon Sep 17 00:00:00 2001 From: Radoslaw Mejer Date: Sat, 23 Nov 2024 22:48:19 +0100 Subject: [PATCH] Fix: add support for the `Name` attribute --- src/Attributes/Argument.php | 2 +- src/Attributes/Description.php | 6 +++--- src/Attributes/Name.php | 6 +++--- src/Attributes/Option.php | 2 +- src/Attributes/Shortcut.php | 6 +++--- src/ProxyFactory.php | 12 +++++++++--- tests/Unit/ProxyFactoryTest.php | 24 ++++++++++++++++++++++++ 7 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/Attributes/Argument.php b/src/Attributes/Argument.php index 8dc9d87..adeaed6 100644 --- a/src/Attributes/Argument.php +++ b/src/Attributes/Argument.php @@ -4,7 +4,7 @@ use Attribute; -#[Attribute(Attribute::TARGET_PARAMETER)] +#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_PROPERTY)] final class Argument { public function __construct() diff --git a/src/Attributes/Description.php b/src/Attributes/Description.php index 9fb8a06..3427ed8 100644 --- a/src/Attributes/Description.php +++ b/src/Attributes/Description.php @@ -4,11 +4,11 @@ use Attribute; -#[Attribute(Attribute::TARGET_PARAMETER)] -final class Description +#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_PROPERTY)] +final readonly class Description { public function __construct( - public readonly string $description, + public string $description, ) { // } diff --git a/src/Attributes/Name.php b/src/Attributes/Name.php index e119f09..0a07a53 100644 --- a/src/Attributes/Name.php +++ b/src/Attributes/Name.php @@ -4,10 +4,10 @@ use Attribute; -#[Attribute(Attribute::TARGET_PARAMETER)] -final class Name +#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_PROPERTY)] +final readonly class Name { - public function __construct(public readonly string $name) + public function __construct(public string $name) { // } diff --git a/src/Attributes/Option.php b/src/Attributes/Option.php index 7994967..cf3d7c7 100644 --- a/src/Attributes/Option.php +++ b/src/Attributes/Option.php @@ -4,7 +4,7 @@ use Attribute; -#[Attribute(Attribute::TARGET_PARAMETER)] +#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_PROPERTY)] final class Option { public function __construct() diff --git a/src/Attributes/Shortcut.php b/src/Attributes/Shortcut.php index 9b9125c..cc40943 100644 --- a/src/Attributes/Shortcut.php +++ b/src/Attributes/Shortcut.php @@ -4,10 +4,10 @@ use Attribute; -#[Attribute(Attribute::TARGET_PARAMETER)] -final class Shortcut +#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_PROPERTY)] +final readonly class Shortcut { - public function __construct(public readonly string $shortcut) + public function __construct(public string $shortcut) { // } diff --git a/src/ProxyFactory.php b/src/ProxyFactory.php index 09e4d58..37cc55d 100644 --- a/src/ProxyFactory.php +++ b/src/ProxyFactory.php @@ -3,6 +3,7 @@ namespace Baethon\Symfony\Console\Input; use Baethon\Symfony\Console\Input\Attributes\Argument; +use Baethon\Symfony\Console\Input\Attributes\Name; use Baethon\Symfony\Console\Input\Attributes\Option; use ReflectionClass; use ReflectionProperty; @@ -43,12 +44,17 @@ function (ReflectionProperty $item) { private function getPropertyData(ReflectionProperty $item, InputInterface $input): array { $option = $item->getAttributes(Option::class)[0] ?? null; - $name = $item->getName(); + $propertyName = $item->getName(); + $name = $item->getAttributes(Name::class)[0] ?? null; + + $name = $name + ? $name->newInstance()->name + : $propertyName; if ($option) { - return [$name, $input->getOption($name)]; + return [$propertyName, $input->getOption($name)]; } - return [$name, $input->getArgument($name)]; + return [$propertyName, $input->getArgument($name)]; } } diff --git a/tests/Unit/ProxyFactoryTest.php b/tests/Unit/ProxyFactoryTest.php index c093b3b..37cb2f8 100644 --- a/tests/Unit/ProxyFactoryTest.php +++ b/tests/Unit/ProxyFactoryTest.php @@ -1,5 +1,7 @@ age)->toEqual(25); expect($ghost->name)->toEqual('Jon'); }); + +it('supports name attribute', function () { + $factory = new ProxyFactory; + $input = new ArrayInput([ + 'foo' => 'Jon', + ], new InputDefinition([ + new InputArgument('foo', mode: InputArgument::REQUIRED), + ])); + + $dto = new class + { + public function __construct( + #[Argument] + #[Name('foo')] + public ?string $name = null + ) {} + }; + + $ghost = $factory->create($dto::class, $input); + + expect($ghost->name)->toEqual('Jon'); +});