PHP Classes

File: tests/ArrayParameterTest.php

Recommend this page to a friend!
  Classes of Rodolfo Berrios Arce   Parameter   tests/ArrayParameterTest.php   Download  
File: tests/ArrayParameterTest.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Parameter
Validate function parameters with PHP attributes
Author: By
Last change:
Date: 15 days ago
Size: 12,131 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\ArrayParameter; use Chevere\Parameter\Interfaces\IntParameterInterface; use Chevere\Parameter\Interfaces\StringParameterInterface; use Chevere\Parameter\Interfaces\UnionParameterInterface; use InvalidArgumentException; use OutOfBoundsException; use PHPUnit\Framework\TestCase; use TypeError; use function Chevere\Parameter\arrayp; use function Chevere\Parameter\assertArray; use function Chevere\Parameter\float; use function Chevere\Parameter\int; use function Chevere\Parameter\null; use function Chevere\Parameter\string; use function Chevere\Parameter\union; final class ArrayParameterTest extends TestCase { public function testConstruct(): void { $parameter = new ArrayParameter(); $this->assertSame(null, $parameter->default()); $this->assertCount(0, $parameter->parameters()); $this->assertSame([ 'type' => 'array#map', 'description' => '', 'default' => null, 'parameters' => [], ], $parameter->schema()); } public function testWithDefault(): void { $parameter = new ArrayParameter(); $int = int(min: 1); $parameter = $parameter->withRequired(test: $int); $default = [ 'test' => 1, ]; $with = $parameter->withDefault($default); $this->assertNotSame($parameter, $with); $this->assertSame($default, $with->default()); (new ParameterHelper())->testWithParameterDefault( primitive: 'array', parameter: $parameter, default: $default, parameterWithDefault: $with ); $this->assertSame([ 'type' => 'array#map', 'description' => '', 'default' => $default, 'parameters' => [ 'test' => [ 'required' => true, ] + $int->schema(), ], ], $with->schema()); $this->expectException(ArgumentCountError::class); $this->expectExceptionMessage('Missing required argument(s): `test`'); $parameter->withDefault([]); } public function testWithRequired(): void { $string = string(); $int = int(); $parameter = new ArrayParameter(); $withRequired = $parameter->withRequired( one: $string, two: $int ); $this->assertTrue($withRequired->parameters()->has('one', 'two')); $this->assertNotSame($parameter, $withRequired); $this->assertCount(2, $withRequired->parameters()); $this->assertInstanceOf( StringParameterInterface::class, $withRequired->parameters()->get('one') ); $this->assertInstanceOf( IntParameterInterface::class, $withRequired->parameters()->get('two') ); $this->assertSame([ 'type' => 'array#map', 'description' => '', 'default' => null, 'parameters' => [ 'one' => [ 'required' => true, ] + $string->schema(), 'two' => [ 'required' => true, ] + $int->schema(), ], ], $withRequired->schema()); $withRequired = $withRequired->withRequired( one: $int, three: $int ); $this->assertTrue($withRequired->parameters()->has('one', 'two', 'three')); $this->assertInstanceOf( IntParameterInterface::class, $withRequired->parameters()->get('one') ); $this->assertInstanceOf( IntParameterInterface::class, $withRequired->parameters()->get('three') ); } public function testWithOptional(): void { $string = string(); $union = union(null(), int()); $parameter = new ArrayParameter(); $with = $parameter->withOptional( one: $string, two: $union ); $assert = assertArray($with, []); $this->assertSame([], $assert); $expected = [ 'two' => null, ]; $assert = assertArray($with, $expected); $this->assertSame($expected, $assert); $expected = [ 'two' => 123, ]; $assert = assertArray($with, $expected); $this->assertSame($expected, $assert); $this->assertTrue($with->parameters()->has('one', 'two')); $this->assertNotSame($parameter, $with); $this->assertCount(2, $with->parameters()); $this->assertInstanceOf( StringParameterInterface::class, $with->parameters()->get('one') ); $this->assertInstanceOf( UnionParameterInterface::class, $with->parameters()->get('two') ); $with = $with->withOptional( one: $union, three: $union ); $this->assertTrue($with->parameters()->has('one', 'two', 'three')); $this->assertInstanceOf( UnionParameterInterface::class, $with->parameters()->get('one') ); $this->assertInstanceOf( UnionParameterInterface::class, $with->parameters()->get('three') ); } public function testWithOut(): void { $string = string(); $int = int(); $parameter = (new ArrayParameter())->withRequired( one: $string, two: $int ); $with = $parameter->without('one'); $this->assertNotSame($parameter, $with); $this->assertCount(1, $with->parameters()); } public function testAssertCompatible(): void { $string = string(); $int = int(); $parameter = (new ArrayParameter())->withRequired( one: $string, ); $altString = string(); $compatible = (new ArrayParameter())->withRequired( one: $altString, ); $parameter->assertCompatible($compatible); $compatible->assertCompatible($parameter); $notCompatible = (new ArrayParameter())->withRequired( one: $int, ); $expectedType = $string::class; $failType = $int::class; $this->expectExceptionMessage( <<<STRING Parameter `one` of type `{$expectedType}` is not compatible with type `{$failType}` STRING ); $this->expectException(InvalidArgumentException::class); $parameter->assertCompatible($notCompatible); } public function testAssertCompatibleMissingKey(): void { $string = string(); $parameter = (new ArrayParameter())->withRequired( one: $string, ); $notCompatible = (new ArrayParameter())->withRequired( two: $string, ); $this->expectException(OutOfBoundsException::class); $parameter->assertCompatible($notCompatible); } public function testIsList(): void { $string = string(); $int = int(); $parameter = (new ArrayParameter())->withRequired( a: $string, b: $int, ); $this->assertFalse($parameter->isList()); $this->assertTrue($parameter->isMap()); $this->assertSame('array#map', $parameter->typeSchema()); $parameter = (new ArrayParameter())->withRequired($string, $int); $this->assertTrue($parameter->isList()); $this->assertFalse($parameter->isMap()); $this->assertSame('array#list', $parameter->typeSchema()); } public function testWithOptionalMinimum(): void { $array = (new ArrayParameter()) ->withOptional( foo: string(), bar: string(), ); $arrayWith = $array->withOptionalMinimum(1); $this->assertNotSame($array, $arrayWith); $this->assertSame(1, $arrayWith->parameters()->optionalMinimum()); } public function testWithMakeOptional(): void { $array = (new ArrayParameter()) ->withRequired( foo: string(), bar: string(), ); $arrayWith = $array->withMakeOptional('foo'); $this->assertNotSame($array, $arrayWith); $this->assertTrue($arrayWith->parameters()->optionalKeys()->contains('foo')); $this->assertTrue($arrayWith->parameters()->requiredKeys()->contains('bar')); } public function testWithMakeRequired(): void { $array = (new ArrayParameter()) ->withOptional( foo: string(), bar: string(), ); $arrayWith = $array->withMakeRequired('bar'); $this->assertNotSame($array, $arrayWith); $this->assertTrue($arrayWith->parameters()->optionalKeys()->contains('foo')); $this->assertTrue($arrayWith->parameters()->requiredKeys()->contains('bar')); } public function testMakeOptionalNoParams(): void { $array = (new ArrayParameter()) ->withRequired( foo: string(), bar: string(), ); $arrayWith = $array->withMakeOptional(); $this->assertNotSame($array, $arrayWith); $this->assertSame([], $arrayWith->parameters()->requiredKeys()->toArray()); $this->assertTrue($arrayWith->parameters()->optionalKeys()->contains('foo', 'bar')); } public function testWithMakeRequiredNoParams(): void { $array = (new ArrayParameter()) ->withOptional( foo: string(), bar: string(), ); $arrayWith = $array->withMakeRequired(); $this->assertNotSame($array, $arrayWith); $this->assertSame([], $arrayWith->parameters()->optionalKeys()->toArray()); $this->assertTrue($arrayWith->parameters()->requiredKeys()->contains('foo', 'bar')); } public function testWithModify(): void { $float = float(); $int = int(); $array = (new ArrayParameter()) ->withRequired( foo: string(), ) ->withOptional( bar: string(), ); $arrayWith = $array->withModify( foo: $float, bar: $int, ); $this->assertNotSame($array, $arrayWith); $this->assertSame( $float, $arrayWith->parameters()->get('foo'), ); $this->assertSame( $int, $arrayWith->parameters()->get('bar'), ); $this->assertSame(['foo'], $arrayWith->parameters()->requiredKeys()->toArray()); $this->assertSame(['bar'], $arrayWith->parameters()->optionalKeys()->toArray()); $this->expectException(OutOfBoundsException::class); $this->expectExceptionMessage('Missing key(s) `0, 1`'); $arrayWith->withModify(...[ 0 => $float, 1 => $int, ]); } public function testInvoke(): void { $value = [ 'name' => 'Rodolfo', 'id' => 10, ]; $parameter = arrayp( name: string(), id: int() ); $parameter($value); $this->expectException(TypeError::class); $parameter(null); } public function testMultipleErrors(): void { $parameter = arrayp( string('/^foo$/'), int(min: 1) ); $parameter(['foo', 1]); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( <<<PLAIN [0]: Argument must be of type Stringable|string, int given [1]: Argument must be of type int, string given PLAIN ); $parameter([1, 'foo']); } }