Skip to content
This repository has been archived by the owner on Jun 11, 2020. It is now read-only.

[WIP] Split Rule to Rule and RuleValidator #7

Merged
merged 4 commits into from
Dec 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"minimum-stability": "stable",
"require": {
"php": ">=7.0",
"psr/http-message": "~1.0"
"symfony/property-access": "^3.4"
},
"require-dev": {
"phpunit/phpunit": "^6.0",
Expand Down
14 changes: 0 additions & 14 deletions src/Rule/Required.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,4 @@
class Required extends Rule
{
protected $message = 'This field is required.';

/**
* {@inheritdoc}
*/
public function verdict($value): VerdictInterface
{
$passes = false;

if (null !== $value) {
$passes = true;
}

return Verdict::create($passes, $this);
}
}
23 changes: 23 additions & 0 deletions src/Rule/RequiredValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Albert221\Validation\Rule;

use Albert221\Validation\Verdict;
use Albert221\Validation\VerdictInterface;

class RequiredValidator extends RuleValidator
{
/**
* {@inheritdoc}
*/
public function verdict($value, Rule $rule): VerdictInterface
{
if (null !== $value) {
return Verdict::create(true, $rule);
}

return Verdict::create(false, $rule);
}
}
22 changes: 9 additions & 13 deletions src/Rule/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ abstract class Rule
/**
* @var array
*/
private $options;
protected $options;

/**
* @var string
Expand All @@ -47,17 +47,12 @@ public function __construct(Validator $validator, Field $field, array $options =
$this->validator = $validator;
}

public function getField(): Field
{
return $this->field;
}

/**
* @return string
* @return Field
*/
public function getFieldName(): string
public function getField(): Field
{
return $this->field->getName();
return $this->field;
}

/**
Expand Down Expand Up @@ -102,11 +97,12 @@ public function setMessage(string $message)
}

/**
* @param $value
*
* @return VerdictInterface
* @return string
*/
abstract public function verdict($value): VerdictInterface;
public function validatedBy(): string
{
return get_class($this) . 'Validator';
}

//
// Methods taken from Field and ValidatorBuilder for easy methods chaining.
Expand Down
18 changes: 18 additions & 0 deletions src/Rule/RuleValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Albert221\Validation\Rule;

use Albert221\Validation\VerdictInterface;

abstract class RuleValidator
{
/**
* @param mixed $value
* @param Rule $rule
*
* @return VerdictInterface
*/
abstract public function verdict($value, Rule $rule): VerdictInterface;
}
23 changes: 23 additions & 0 deletions src/RuleValidatorFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Albert221\Validation;

use Albert221\Validation\Rule\Rule;
use Albert221\Validation\Rule\RuleValidator;

class RuleValidatorFactory
{
/**
* @param Rule $rule
*
* @return RuleValidator
*/
public function getInstance(Rule $rule): RuleValidator
{
$validatorName = $rule->validatedBy();

return new $validatorName();
}
}
31 changes: 29 additions & 2 deletions src/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@

namespace Albert221\Validation;

use Albert221\Validation\Rule\Validator\RuleValidator;
use InvalidArgumentException;
use RuntimeException;
use Symfony\Component\PropertyAccess\PropertyAccess;

class Validator
{
/**
* @var RuleValidatorFactory
*/
private $ruleValidatorFactory;

/**
* @var Field[]
*/
Expand All @@ -21,6 +29,14 @@ public static function build()
return new self();
}

/**
* Validator constructor.
*/
public function __construct()
{
$this->ruleValidatorFactory = new RuleValidatorFactory();
}

/**
* @return Field[]
*/
Expand Down Expand Up @@ -77,12 +93,23 @@ public function addField(string $name): Field
*/
public function validate($data): VerdictList
{
$propertyAccessor = PropertyAccess::createPropertyAccessor();

$verdicts = [];
foreach ($this->fields as $field) {
$value = $data[$field->getName()] ?? null;
try {
$value = $propertyAccessor->getValue(
$data,
is_array($data) ? "[" . $field->getName() . "]" : $field->getName()
);
} catch (RuntimeException $e) {
$value = null;
}

foreach ($field->getRules() as $rule) {
$verdicts[] = $rule->verdict($value);
$ruleValidator = $this->ruleValidatorFactory->getInstance($rule);

$verdicts[] = $ruleValidator->verdict($value, $rule);
}
}

Expand Down
7 changes: 3 additions & 4 deletions tests/EverythingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function setUp()
*/
public function testEverything(bool $shouldBeValid, array $data)
{
$valid = Validator::build()
$verdicts = Validator::build()
->addField('username')
->addRule(Rule\Required::class)
// ->addRule(Rule\Length::class, ['min' => 4])
Expand All @@ -70,10 +70,9 @@ public function testEverything(bool $shouldBeValid, array $data)
->addField('confirm_password')
->addRule(Rule\Required::class)
// ->addRule(Rule\SameAs::class, ['field' => 'password'])
->validate($data)
->passes();
->validate($data);

$this->assertEquals($shouldBeValid, $valid);
$this->assertEquals($shouldBeValid, $verdicts->passes());
}

/**
Expand Down
18 changes: 18 additions & 0 deletions tests/TestValidateRuleValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Albert221\Validation;

use Albert221\Validation\Rule\Rule;
use Albert221\Validation\Rule\RuleValidator;

class TestValidateRuleValidator extends RuleValidator
{
public static $called = false;
public function verdict($value, Rule $rule): VerdictInterface
{
self::$called = true;
return Verdict::create(true, $rule);
}
}
18 changes: 4 additions & 14 deletions tests/ValidatorTest.php → tests/ValidatorTestValidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Albert221\Validation;

use Albert221\Validation\Rule\Rule;
use Albert221\Validation\Rule\RuleValidator;
use PHPUnit\Framework\TestCase;

class ValidatorTest extends TestCase
Expand Down Expand Up @@ -72,20 +73,9 @@ public function testValidate()
$validator = new Validator();

$rule = new class($validator, $this->createMock(Field::class)) extends Rule {
public $verdict = false;

public function verdict($value): VerdictInterface
public function validatedBy(): string
{
$this->verdict = true;
return new class implements VerdictInterface {
public function getField(): Field
{
}

public function passes(): bool
{
}
};
return TestValidateRuleValidator::class;
}
};

Expand All @@ -95,7 +85,7 @@ public function passes(): bool
->validate([]);

// Assert that verdict method was called on rules.
$this->assertTrue($rule->verdict);
$this->assertTrue(TestValidateRuleValidator::$called);
$this->assertInstanceOf(VerdictList::class, $verdicts);
}
}
32 changes: 32 additions & 0 deletions tests/VerdictListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,38 @@ public function testFails()
$this->assertTrue($list->fails());
}

public function testToArray()
{
$verdictList = new VerdictList([
$this->getPassingVerdict()
]);

$this->assertInternalType('array', $verdictList->toArray());
}

public function testCount()
{
$verdictList = new VerdictList([
$this->getPassingVerdict(),
$this->getPassingVerdict(),
$this->getFailingVerdict()
]);

$this->assertEquals(3, $verdictList->count());
}

public function testGetIterator()
{
$firstVerdict = $this->getPassingVerdict();

$verdictList = new VerdictList([
$firstVerdict,
$this->getPassingVerdict()
]);

$this->assertEquals($firstVerdict, $verdictList->getIterator()->getArrayCopy()[0]);
}

/**
* @return VerdictInterface
*/
Expand Down