Skip to content

Commit

Permalink
close #9
Browse files Browse the repository at this point in the history
  • Loading branch information
rodber committed Jan 13, 2025
1 parent fc901f2 commit 70a5873
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 94 deletions.
49 changes: 49 additions & 0 deletions src/Attributes/UnionAttr.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/*
* This file is part of Chevere.
*
* (c) Rodolfo Berrios <rodolfo@chevere.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Chevere\Parameter\Attributes;

use Attribute;
use Chevere\Parameter\Interfaces\ParameterAttributeInterface;
use Chevere\Parameter\Interfaces\ParameterInterface;
use Chevere\Parameter\Interfaces\UnionParameterInterface;
use Chevere\Parameter\Parameters;
use Chevere\Parameter\UnionParameter;

#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_PARAMETER | Attribute::TARGET_CLASS_CONSTANT)]
class UnionAttr implements ParameterAttributeInterface
{
public readonly UnionParameterInterface $parameter;

public function __construct(
ParameterAttributeInterface ...$parameterAttribute,
) {
$parameters = new Parameters();
foreach ($parameterAttribute as $name => $attribute) {
$name = (string) $name;
$parameters = $parameters
->withRequired($name, $attribute->parameter());
}
$this->parameter = new UnionParameter($parameters);
}

public function __invoke(mixed $mixed): mixed
{
return $this->parameter->__invoke($mixed);
}

public function parameter(): ParameterInterface
{
return $this->parameter;
}
}
8 changes: 8 additions & 0 deletions src/Attributes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ function iteratorAttr(string $name): IterableAttr
return parameterAttr($name, $caller['function'], $caller['class'] ?? '');
}

function unionAttr(string $name): UnionAttr
{
$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1];

// @phpstan-ignore-next-line
return parameterAttr($name, $caller['function'], $caller['class'] ?? '');
}

function returnAttr(): ReturnAttr
{
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
Expand Down
137 changes: 43 additions & 94 deletions tests/Attribute/UsesParameterAttributesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,118 +21,66 @@

final class UsesParameterAttributesTest extends TestCase
{
public const DEFAULT_ARGUMENTS = [
'name' => 'Test',
'age' => 12,
'cols' => [
'id' => 1,
],
'tags' => ['Chevere', 'Chevere', 'Chevere', 'Uh'],
'flag' => false,
'amount' => 0,
'null' => null,
'enum' => 'value',
'union' => 1,
];

public function dataProviderWillSuccess(): array
{
return [
[
'name' => 'Rodolfo',
'age' => 25,
'cols' => [
'id' => 1,
],
'tags' => ['Chevere', 'Chevere', 'Chevere', 'Uh'],
'flag' => false,
'amount' => 0,
'null' => null,
'enum' => 'test',
],
static::DEFAULT_ARGUMENTS,
];
}

public function dataProviderWillFail(): array
{
return [
[
array_merge(static::DEFAULT_ARGUMENTS, [
'name' => 'Peoples Hernandez',
'age' => 66,
'cols' => [
'id' => 1,
],
'tags' => ['people'],
'flag' => false,
'amount' => 0,
'null' => null,
'enum' => 'test',
'error' => "Argument value provided `Peoples Hernandez` doesn't match the regex `/^[A-Za-z]+$/`",
],
[
'name' => 'zerothehero',
'error' => "[name]: Argument value provided `Peoples Hernandez` doesn't match the regex `/^[A-Za-z]+$/`",
]),
array_merge(static::DEFAULT_ARGUMENTS, [
'age' => 0,
'cols' => [
'id' => 1,
],
'tags' => ['zero'],
'flag' => false,
'amount' => 0,
'null' => null,
'enum' => 'test',
'error' => 'Argument value provided `0` is less than `1`',
],
[
'name' => 'SergioDalmata',
'error' => '[age]: Argument value provided `0` is less than `1`',
]),
array_merge(static::DEFAULT_ARGUMENTS, [
'age' => 101,
'cols' => [
'id' => 1,
],
'tags' => ['dalmata'],
'flag' => false,
'amount' => 0,
'null' => null,
'enum' => 'test',
'error' => 'Argument value provided `101` is greater than `100`',
],
[
'name' => 'DonZeroId',
'age' => 42,
'error' => '[age]: Argument value provided `101` is greater than `100`',
]),
array_merge(static::DEFAULT_ARGUMENTS, [
'cols' => [
'id' => 0,
],
'tags' => ['zeroid'],
'flag' => false,
'amount' => 0,
'null' => null,
'enum' => 'test',
'error' => '[id]: Argument value provided `0` is less than `1`',
],
[
'name' => 'iterableNull',
'age' => 24,
'cols' => [
'id' => 42,
],
'error' => '[cols]: [id]: Argument value provided `0` is less than `1`',
]),
array_merge(static::DEFAULT_ARGUMENTS, [
'tags' => [123],
'flag' => false,
'amount' => 0,
'null' => null,
'enum' => 'test',
'error' => 'Argument #1 ($value) must be of type Stringable|string, int given',
],
[
'name' => 'negativeAmount',
'age' => 24,
'cols' => [
'id' => 42,
],
'tags' => ['test'],
'flag' => false,
'error' => '[tags]: [V *iterable]: Argument #1 ($value) must be of type Stringable|string, int given',
]),
array_merge(static::DEFAULT_ARGUMENTS, [
'amount' => -10.5,
'null' => null,
'enum' => 'test',
'error' => 'Argument value provided `-10.5` is less than `0`',
],
[
'name' => 'wrongEnum',
'age' => 24,
'cols' => [
'id' => 42,
],
'tags' => ['test'],
'flag' => false,
'amount' => 100.5,
'null' => null,
'error' => '[amount]: Argument value provided `-10.5` is less than `0`',
]),
array_merge(static::DEFAULT_ARGUMENTS, [
'enum' => 'try',
'error' => "Argument value provided `try` doesn't match the regex `/\b(test|value)\b/`",
],
'error' => "[enum]: Argument value provided `try` doesn't match the regex `/\b(test|value)\b/`",
]),
array_merge(static::DEFAULT_ARGUMENTS, [
'union' => 0,
'error' => <<<PLAIN
[union]: Argument provided doesn't match union: Parameter `0` <Chevere\Parameter\IntParameter>: Argument value provided `0` is less than `1`; Parameter `1` <Chevere\Parameter\StringParameter>: Argument #1 (\$value) must be of type Stringable|string, int given
PLAIN,
]),
];
}

Expand All @@ -148,6 +96,7 @@ public function testWillFail(
float $amount,
mixed $null,
string $enum,
int|string $union,
string $error
): void {
$this->expectException(InvalidArgumentException::class);
Expand Down
8 changes: 8 additions & 0 deletions tests/src/UsesAttr.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Chevere\Parameter\Attributes\NullAttr;
use Chevere\Parameter\Attributes\ReturnAttr;
use Chevere\Parameter\Attributes\StringAttr;
use Chevere\Parameter\Attributes\UnionAttr;
use Chevere\Parameter\Interfaces\ParameterInterface;
use function Chevere\Parameter\Attributes\arrayArguments;
use function Chevere\Parameter\Attributes\arrayAttr;
Expand All @@ -34,6 +35,7 @@
use function Chevere\Parameter\Attributes\nullAttr;
use function Chevere\Parameter\Attributes\returnAttr;
use function Chevere\Parameter\Attributes\stringAttr;
use function Chevere\Parameter\Attributes\unionAttr;
use function Chevere\Parameter\Attributes\valid;
use function Chevere\Parameter\int;

Expand Down Expand Up @@ -65,6 +67,11 @@ public function __construct(
mixed $null = null,
#[EnumAttr('test', 'value')]
string $enum = 'value',
#[UnionAttr(
new IntAttr(min: 1),
new StringAttr('/^[A-Za-z]+$/'),
)]
int|string $union = 1,
) {
// Validate all
valid();
Expand All @@ -85,6 +92,7 @@ public function __construct(
$amount = floatAttr('amount')($amount);
$null = nullAttr('null')($null);
$enum = enumAttr('enum')($enum);
$union = unionAttr('union')($union);
// Validate return attr
returnAttr()($id);
}
Expand Down

0 comments on commit 70a5873

Please sign in to comment.