diff --git a/src/UnionParameter.php b/src/UnionParameter.php index 8201b38..0068c4e 100644 --- a/src/UnionParameter.php +++ b/src/UnionParameter.php @@ -20,6 +20,9 @@ use Chevere\Parameter\Traits\ArrayParameterTrait; use Chevere\Parameter\Traits\ParameterAssertArrayTypeTrait; use Chevere\Parameter\Traits\ParameterTrait; +use Throwable; +use TypeError; +use function Chevere\Message\message; final class UnionParameter implements UnionParameterInterface { @@ -42,7 +45,28 @@ final public function __construct( public function __invoke(mixed $value): mixed { - return assertUnion($this, $value); + $types = []; + $errors = []; + foreach ($this->parameters() as $item) { + try { + assertNamedArgument('', $item, $value); + + return $value; + } catch (Throwable $e) { + $types[] = $item::class; + $errors[] = $e->getMessage(); + } + } + $types = implode('|', $types); + $errors = implode('; ', $errors); + + throw new TypeError( + (string) message( + "Argument provided doesn't match the union type `%types%`. Error(s): %errors%", + types: $types, + errors: $errors, + ) + ); } public function withAdded(ParameterInterface ...$parameter): static diff --git a/src/functions.php b/src/functions.php index ae45719..3f07c49 100644 --- a/src/functions.php +++ b/src/functions.php @@ -35,7 +35,6 @@ use ReflectionMethod; use ReflectionParameter; use Throwable; -use TypeError; use function Chevere\Message\message; function cast(mixed $argument): CastInterface @@ -92,29 +91,6 @@ function arguments( return new Arguments($parameters, $arguments); } -function assertUnion( - UnionParameterInterface $parameter, - mixed $argument, -): mixed { - $types = []; - foreach ($parameter->parameters() as $item) { - try { - assertNamedArgument('', $item, $argument); - - return $argument; - } catch (Throwable $e) { - $types[] = $item::class; - } - } - - throw new TypeError( - (string) message( - "Argument provided doesn't match the union type `%type%`", - type: implode('|', $types) - ) - ); -} - function assertNamedArgument( string $name, ParameterInterface $parameter, diff --git a/tests/FunctionsTest.php b/tests/FunctionsTest.php index cd8c8ac..f8486bf 100644 --- a/tests/FunctionsTest.php +++ b/tests/FunctionsTest.php @@ -24,7 +24,6 @@ use function Chevere\Parameter\arrayp; use function Chevere\Parameter\assertArray; use function Chevere\Parameter\assertNamedArgument; -use function Chevere\Parameter\assertUnion; use function Chevere\Parameter\bool; use function Chevere\Parameter\float; use function Chevere\Parameter\generic; @@ -37,7 +36,6 @@ use function Chevere\Parameter\string; use function Chevere\Parameter\takeFrom; use function Chevere\Parameter\takeKeys; -use function Chevere\Parameter\union; final class FunctionsTest extends TestCase { @@ -211,18 +209,6 @@ public function testFunctionGenericParameter(): void $this->assertSame('foo', $parameter->description()); } - public function testFunctionUnionParameter(): void - { - $parameter = union( - int(), - string(), - ); - assertUnion($parameter, 'foo'); - assertUnion($parameter, 123); - $this->expectException(TypeError::class); - assertUnion($parameter, []); - } - public function testAssertArrayExtraArguments(): void { $parameter = arrayp( diff --git a/tests/FunctionsUnionTest.php b/tests/FunctionsUnionTest.php deleted file mode 100644 index 93eda36..0000000 --- a/tests/FunctionsUnionTest.php +++ /dev/null @@ -1,105 +0,0 @@ - - * - * 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\Tests; - -use InvalidArgumentException; -use PHPUnit\Framework\TestCase; -use TypeError; -use function Chevere\Parameter\arrayp; -use function Chevere\Parameter\assertGeneric; -use function Chevere\Parameter\assertUnion; -use function Chevere\Parameter\generic; -use function Chevere\Parameter\int; -use function Chevere\Parameter\null; -use function Chevere\Parameter\union; - -final class FunctionsUnionTest extends TestCase -{ - public function testUnionArrayFixed(): void - { - $array = arrayp(a: int()); - $union = union(arrayp(), $array); - $argument = [ - 'a' => 1, - ]; - assertUnion($union, []); - assertUnion($union, $argument); - $union = union($array, null()); - assertUnion($union, $argument); - $this->expectException(TypeError::class); - assertUnion($union, []); - } - - public function testUnionArrayGeneric(): void - { - $array = arrayp(a: int()); - $generic = generic($array); - $union = union(arrayp(), $generic); - $argument = [ - [ - 'a' => 1, - ], - [ - 'a' => 2, - ], - ]; - assertUnion($union, []); - assertUnion($union, $argument); - $union = union($generic, null()); - assertUnion($union, $argument); - $this->expectException(TypeError::class); - assertUnion($union, []); - } - - public function testUnionGenericEmptyArray(): void - { - $array = arrayp(a: int()); - $union = union(arrayp(), $array); - $generic = generic($union); - $argument = [ - [ - 'a' => 1, - ], - [ - 'a' => 2, - ], - ]; - assertGeneric($generic, $argument); - assertGeneric($generic, [[]]); - $generic = generic(union($array, null())); - assertGeneric($generic, $argument); - $this->expectException(InvalidArgumentException::class); - assertGeneric($generic, [[]]); - } - - public function testUnionGeneric(): void - { - $generic = generic(int()); - $union = union(arrayp(), $generic); - assertUnion($union, []); - assertUnion($union, [1, 2, 3]); - $this->expectException(TypeError::class); - assertUnion($union, [[]]); - } - - public function testUnionGenericArray(): void - { - $generic = generic(arrayp()); - $union = union(arrayp(), $generic); - assertUnion($union, []); - assertUnion($union, [[]]); - $this->expectException(TypeError::class); - assertUnion($union, [[[]]]); - } -}