PHP Classes

File: tests/ArgumentsTest.php

Recommend this page to a friend!
  Classes of Rodolfo Berrios Arce   Parameter   tests/ArgumentsTest.php   Download  
File: tests/ArgumentsTest.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Parameter
Validate function parameters with PHP attributes
Author: By
Last change:
Date: 20 days ago
Size: 12,606 bytes
 

Contents

Class file image Download
<?php /* * This file is part of Chevere. * * (c) Rodolfo Berrios <[email protected]> * * 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 ArgumentCountError; use Chevere\Parameter\Arguments; use Chevere\Parameter\Interfaces\ArrayParameterInterface; use Chevere\Parameter\IntParameter; use Chevere\Parameter\Parameters; use Chevere\Regex\Regex; use Chevere\Tests\src\ArrayAccessDynamic; use Chevere\Tests\src\ArrayAccessMixed; use Chevere\Tests\src\ArrayAccessScoped; use InvalidArgumentException; use OutOfBoundsException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use stdClass; use TypeError; use function Chevere\Parameter\arrayp; use function Chevere\Parameter\bool; use function Chevere\Parameter\int; use function Chevere\Parameter\parameters; use function Chevere\Parameter\string; final class ArgumentsTest extends TestCase { public function testInvalidArgument(): void { $parameters = parameters(test: string()); $this->assertTrue($parameters->requiredKeys()->contains('test')); $this->assertFalse($parameters->optionalKeys()->contains('test')); $this->expectException(InvalidArgumentException::class); new Arguments($parameters, [ 'test' => 123, ]); } public function testConstruct(): void { $args = [ 'id' => 1, 'name' => 'someValue', ]; $parameters = parameters( id: new IntParameter(), name: string() ); $arguments = new Arguments($parameters, $args); $this->assertSame($parameters, $arguments->parameters()); $this->assertSame($args, $arguments->toArray()); foreach ($args as $name => $value) { $this->assertTrue($arguments->has($name)); $this->assertSame($value, $arguments->get($name)); } $notFoundKey = '404'; $this->assertFalse($arguments->has($notFoundKey)); $this->expectException(OutOfBoundsException::class); $arguments->get($notFoundKey); } public function testMissingArgument(): void { $parameters = parameters(test: string()); $this->expectException(ArgumentCountError::class); new Arguments($parameters, []); } public function testIgnoreExtraArguments(): void { $parameters = parameters(test: string()); $arguments = new Arguments($parameters, [ 'test' => '123', 'extra' => 'nono', ]); $this->assertSame($arguments->toArray(), [ 'test' => '123', ]); } public function testInvalidArgumentType(): void { $parameters = parameters(test: string()); $this->expectException(InvalidArgumentException::class); new Arguments($parameters, [ 'test' => 123, ]); } public function testInvalidRegexArgument(): void { $parameters = parameters( id: string() ->withRegex(new Regex('/^[0-9]+$/')), ); $this->expectException(InvalidArgumentException::class); new Arguments($parameters, [ 'id' => 'abc', ]); } public function testWithMissingArgument(): void { $name = 'test'; $parameters = parameters(test: string()); $arguments = new Arguments($parameters, [ $name => '123', ]); $this->expectException(OutOfBoundsException::class); $arguments->withPut('notFound', '1234'); } public function testWithArgument(): void { $name = 'id'; $value = '123'; $valueAlt = '321'; $arguments = new Arguments( parameters( id: string() ->withRegex(new Regex('/^[0-9]+$/')) ), [ $name => $value, ] ); $this->assertTrue($arguments->has($name)); $this->assertSame($value, $arguments->get($name)); $argumentsWith = $arguments->withPut($name, $valueAlt); $this->assertNotSame($arguments, $argumentsWith); $this->assertSame($valueAlt, $argumentsWith->get($name)); $this->expectException(InvalidArgumentException::class); $argumentsWith->withPut($name, 'invalid'); } public function testWithArgumentTypeError(): void { $name = 'id'; $value = '123'; $valueAlt = '321'; $arguments = new Arguments( parameters( id: string() ), [ $name => $value, ] ); $this->expectException(TypeError::class); $arguments->withPut($name, 123); } public function testWithArgumentWrongTypeValue(): void { $arguments = new Arguments( parameters( id: string() ), [ 'id' => '123', ] ); $this->expectException(TypeError::class); $arguments->withPut('id', 123); } public function testArgumentsRequiredException(): void { $parameters = parameters( id: string() ->withRegex(new Regex('/^[0-9]+$/')) ); $this->expectException(ArgumentCountError::class); new Arguments($parameters, []); } public function testParameterOptional(): void { $parameters = parameters(id: string()) ->withOptional('opt', string()) ->withOptional('alt', string()) ->withRequired('name', string()); $arguments = new Arguments( $parameters, [ 'id' => '123', 'name' => 'ABC', ] ); $this->assertTrue($arguments->has('id', 'name')); $this->assertFalse($arguments->has('opt', 'alt')); $arguments = new Arguments( $parameters, [ 'id' => '123', 'opt' => 'someValue', 'name' => 'ABC', ] ); $this->assertTrue($arguments->has('id', 'name', 'opt')); $this->assertFalse($arguments->has('alt')); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('[name]'); $arguments = new Arguments( $parameters, [ 'id' => '123', 'name' => new stdClass(), ] ); } public function testParameterDefault(): void { $optional = 'name'; $default = 'a'; $parameters = parameters() ->withOptional( $optional, string() ->withRegex(new Regex('/^a|b$/')) ->withDefault($default), ); $arguments = new Arguments( $parameters, [] ); $this->assertTrue($arguments->has($optional)); $this->assertSame($default, $arguments->get($optional)); $this->assertSame( [ $optional => $default, ], $arguments->toArray() ); } public function testArgumentDefaultOverride(): void { $optionalString = 'string'; $optionalStringDefault = 'a'; $optionalStringValue = 'b'; $optionalInt = 'int'; $parameters = parameters() ->withOptional( $optionalString, string() ->withRegex(new Regex('/^a|b$/')) ->withDefault($optionalStringDefault), ); $arguments = new Arguments( $parameters, [ $optionalString => $optionalStringValue, ] ); $this->assertFalse($arguments->has($optionalInt)); $this->assertTrue($arguments->has($optionalString)); $this->assertEquals( [ $optionalString => $optionalStringValue, ], $arguments->toArray() ); } public function testToArrayFill(): void { $parameters = parameters( foo: string(default: 'bar') ) ->withOptional('name', string()) ->withOptional('id', string()); $arguments = new Arguments($parameters, []); $this->assertFalse($arguments->has('name', 'id')); $this->assertEquals([ 'foo' => 'bar', ], $arguments->toArray()); $this->assertSame( [ 'name' => null, 'id' => null, 'foo' => 'bar', ], $arguments->toArrayFill(null) ); } public function testSkipOptional(): void { $parameters = parameters() ->withOptional('name', string()) ->withOptional('id', string()); $expected = [ 'name' => 'foo', 'id' => 'bar', ]; $arguments = new Arguments($parameters, $expected); // $this->assertFalse($arguments->isSkipOptional('name')); $this->assertSame($expected, $arguments->toArray()); } public function testCast(): void { $foo = 'foo'; $var = true; $parameters = parameters( foo: bool(), ); $arguments = new Arguments( $parameters, [ $foo => $var, ] ); $this->assertSame($var, $arguments->required($foo)->bool()); $this->expectException(InvalidArgumentException::class); $arguments->optional($foo); } public function testCastOptional(): void { $foo = 'foo'; $var = true; $parameters = parameters()->withOptional($foo, bool()); $arguments = new Arguments( $parameters, [ $foo => $var, ] ); $this->assertSame($var, $arguments->optional($foo)?->bool()); $arguments = new Arguments($parameters, []); $this->assertNull($arguments->optional($foo)); $this->expectException(InvalidArgumentException::class); $arguments->required($foo); } #[DataProvider('dataProviderArrayAccess')] public function testArrayAccess( ArrayParameterInterface $parameter, \ArrayAccess $arrayAccess, array $array ): void { $arguments = new Arguments($parameter->parameters(), $arrayAccess); $this->assertSame($array, $arguments->toArray()); } public static function dataProviderArrayAccess(): array { $named = [ 'string' => 'test', 'int' => 1, 'bool' => false, ]; $parameter = arrayp( string: string(), int: int(), bool: bool() ); return [ [ arrayp(), new ArrayAccessDynamic([]), [], ], [ $parameter, new ArrayAccessScoped(...$named), $named, ], [ $parameter, new ArrayAccessDynamic($named), $named, ], [ $parameter->withRequired( dynamic: string() ), new ArrayAccessMixed(...$named), $named + [ 'dynamic' => '123abc', ], ], ]; } public function testMinimumOptional(): void { $parameters = (new Parameters(foo: string())) ->withOptional('bar', string()); new Arguments($parameters, [ 'foo' => '', ]); $parameters = $parameters->withOptionalMinimum(1); new Arguments($parameters, [ 'foo' => '', 'bar' => '', ]); $this->expectException(ArgumentCountError::class); new Arguments($parameters, [ 'foo' => '', ]); } public function testOptionalNullPass(): void { $parameters = (new Parameters())->withOptional('foo', string()); $arguments = [ 'foo' => 'string', ]; new Arguments($parameters, $arguments); $arguments = [ 'foo' => null, ]; $this->expectException(InvalidArgumentException::class); new Arguments($parameters, $arguments); } }