Skip to content

Commit

Permalink
Merge pull request #49 from MarioDevment/feat/add-set-handler-method-…
Browse files Browse the repository at this point in the history
…and-cascade-request

add set handler method and cascade request
  • Loading branch information
klaussilveira authored Apr 24, 2020
2 parents 9024a78 + 94fb0be commit dbdad6e
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 23 deletions.
4 changes: 2 additions & 2 deletions src/InputHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ public function __construct(TypeHandler $typeHandler = null)
$this->root->setTypeHandler($this->typeHandler);
}

public function add(string $key, string $type, array $options = []): BaseNode
public function add(string $key, string $type, array $options = [], InputHandler $handler = null): BaseNode
{
return $this->root->add($key, $type, $options);
return $this->root->add($key, $type, $options, $handler);
}

public function remove(string $key): void
Expand Down
68 changes: 47 additions & 21 deletions src/Node/BaseNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ class BaseNode
*/
protected $required = true;

/**
* @var mixed
*/
protected $default;

/**
Expand All @@ -64,64 +61,86 @@ class BaseNode
*/
protected $allowNull = false;

public function setConstraints(array $constraints): void
public function setConstraints(array $constraints): self
{
$this->constraints = $constraints;

return $this;
}

public function addConstraint(ConstraintInterface $constraint): void
public function addConstraint(ConstraintInterface $constraint): self
{
$this->constraints[] = $constraint;

return $this;
}

public function addConstraints(array $constraints): void
public function addConstraints(array $constraints): self
{
$this->constraints = array_merge($this->constraints, $constraints);

return $this;
}

public function setTransformer(TransformerInterface $transformer): void
public function setTransformer(TransformerInterface $transformer): self
{
$this->transformer = $transformer;

return $this;
}

public function setInstantiator(InstantiatorInterface $instantiator): void
public function setInstantiator(InstantiatorInterface $instantiator): self
{
$this->instantiator = $instantiator;

return $this;
}

public function setTypeHandler(TypeHandler $typeHandler): void
public function setTypeHandler(TypeHandler $typeHandler): self
{
$this->typeHandler = $typeHandler;

return $this;
}

public function setType(string $type): void
public function setType(string $type): self
{
$this->type = $type;

return $this;
}

public function setTypeAlias(string $typeAlias): void
public function setTypeAlias(string $typeAlias): self
{
$this->typeAlias = $typeAlias;

return $this;
}

public function getTypeAlias(): string
{
return $this->typeAlias;
}

public function setRequired(bool $required): void
public function setRequired(bool $required): self
{
$this->required = $required;

return $this;
}

public function setDefault($default): void
public function setDefault($default): self
{
$this->default = $default;

return $this;
}

public function setAllowNull(bool $allowNull): void
public function setAllowNull(bool $allowNull): self
{
$this->allowNull = $allowNull;

return $this;
}

public function getDefault()
Expand All @@ -134,17 +153,16 @@ public function hasDefault(): bool
return (bool) $this->default;
}

public function add(string $key, string $type, array $options = []): BaseNode
public function add(string $key, string $type, array $options = [], InputHandler $handler = null): BaseNode
{
$child = $this->typeHandler->getType($type);

if (isset($options['handler'])) {
/** @var InputHandler $handler */
$handler = $options['handler'];
$handler->setRootType($type);
$handler->define();
if (isset($handler)) {
$child = $child->setHandler($handler, $type);
}

$child = $handler->getRoot();
if (isset($options['handler']) && !isset($handler)) {
$child = $child->setHandler($options['handler'], $type);
}

if (isset($options['required'])) {
Expand Down Expand Up @@ -262,4 +280,12 @@ protected function checkConstraints(string $field, $value): void
}
}
}

private function setHandler(InputHandler $handler, string $type): self
{
$handler->setRootType($type);
$handler->define();

return $handler->getRoot();
}
}
149 changes: 149 additions & 0 deletions tests/InputHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

namespace Linio\Component\Input;

use Linio\Component\Input\Constraint\Email;
use Linio\Component\Input\Constraint\Enum;
use Linio\Component\Input\Constraint\Range;
use Linio\Component\Input\Constraint\StringSize;
use Linio\Component\Input\Instantiator\InstantiatorInterface;
use Linio\Component\Input\Instantiator\PropertyInstantiator;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -99,6 +102,16 @@ public function define(): void
}
}

class TestRecursiveInputHandlerExplicit extends InputHandler
{
public function define(): void
{
$this->add('title', 'string');
$this->add('size', 'int');
$this->add('child', \stdClass::class, ['instantiator' => new PropertyInstantiator()], new TestInputHandler());
}
}

class TestNullableInputHandler extends InputHandler
{
public function define(): void
Expand All @@ -121,6 +134,31 @@ public function define(): void
}
}

class TestInputHandlerCascade extends InputHandler
{
public function define(): void
{
$this->add('name', 'string')
->setRequired(true)
->addConstraint(new StringSize(1, 80));

$this->add('age', 'int')
->setRequired(true)
->addConstraint(new Range(1, 99));

$this->add('gender', 'string')
->setRequired(true)
->addConstraint(new Enum(['male', 'female', 'other']));

$this->add('birthday', 'datetime')
->setRequired(false);

$this->add('email', 'string')
->setRequired(false)
->addConstraint(new Email());
}
}

class InputHandlerTest extends TestCase
{
public function testIsHandlingBasicInput(): void
Expand Down Expand Up @@ -464,6 +502,102 @@ public function testIsHandlingInputWithRecursiveHandler(): void
$this->assertEquals([$fanA, $fanB, $fanC], $child->fans);
}

public function testIsHandlingInputWithRecursiveHandlerExplicit(): void
{
$input = [
'title' => 'Barfoo',
'size' => 20,
'child' => [
'title' => 'Foobar',
'size' => 35,
'dimensions' => [11, 22, 33],
'date' => '2015-01-01 22:50',
'metadata' => [
'foo' => 'bar',
],
'simple' => [
'date' => '2015-01-01 22:50',
],
'user' => [
'name' => false,
'age' => '28',
],
'author' => [
'name' => 'Barfoo',
'age' => 28,
'related' => [
'name' => 'Barfoo',
'age' => 28,
],
],
'fans' => [
[
'name' => 'A',
'age' => 18,
'birthday' => '2000-01-01',
],
[
'name' => 'B',
'age' => 28,
'birthday' => '2000-01-02',
],
[
'name' => 'C',
'age' => 38,
'birthday' => '2000-01-03',
],
],
],
];

$inputHandler = new TestRecursiveInputHandlerExplicit();
$inputHandler->bind($input);
$this->assertTrue($inputHandler->isValid());

// Basic fields
$this->assertEquals('Barfoo', $inputHandler->getData('title'));
$this->assertEquals(20, $inputHandler->getData('size'));
/** @var \stdClass $child */
$child = $inputHandler->getData('child');

// Scalar collection
$this->assertEquals([11, 22, 33], $child->dimensions);

// Transformer
$this->assertEquals(new \DateTime('2015-01-01 22:50'), $child->date);

// Mixed array
$this->assertEquals(['foo' => 'bar'], $child->metadata);

// Typed array
$this->assertEquals(['title' => 'Barfoo', 'size' => 15, 'date' => new \DateTime('2015-01-01 22:50')], $child->simple);

// Object and nested object
$related = new TestUser();
$related->setName('Barfoo');
$related->setAge(28);
$author = new TestUser();
$author->setName('Barfoo');
$author->setAge(28);
$author->setRelated($related);
$this->assertEquals($author, $child->author);

// Object collection
$fanA = new TestUser();
$fanA->setName('A');
$fanA->setAge(18);
$fanA->setBirthday(new \DateTime('2000-01-01'));
$fanB = new TestUser();
$fanB->setName('B');
$fanB->setAge(28);
$fanB->setBirthday(new \DateTime('2000-01-02'));
$fanC = new TestUser();
$fanC->setName('C');
$fanC->setAge(38);
$fanC->setBirthday(new \DateTime('2000-01-03'));
$this->assertEquals([$fanA, $fanB, $fanC], $child->fans);
}

public function testOverride(): void
{
$input = [
Expand Down Expand Up @@ -539,6 +673,21 @@ public function testIsHandlingInputWithNullValues(): void

$this->assertNull($data);
}

public function testInputHandlerOnCascade(): void
{
$input = [
'name' => 'A',
'age' => 18,
'gender' => 'male',
'birthday' => '2000-01-01',
];

$inputHandler = new TestInputHandlerCascade();
$inputHandler->bind($input);

$this->assertTrue($inputHandler->isValid());
}
}

class TestConstraintOverrideType extends InputHandler
Expand Down

0 comments on commit dbdad6e

Please sign in to comment.