Skip to content

Commit

Permalink
馃摝 NEW: Add Validator class
Browse files Browse the repository at this point in the history
  • Loading branch information
elie29 committed Feb 20, 2019
1 parent e427b45 commit c6199c0
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/Rule/AbstractRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function getKey(): string
return $this->key;
}

public function getValue(): string
public function getValue()
{
return $this->value;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Rule/RuleInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function getKey(): string;
* Retrieve the value. Value will be trimmed
* if trim is set to true.
*
* @return string
* @return mixed
*/
public function getValue(): string;
public function getValue();
}
126 changes: 126 additions & 0 deletions src/Validator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

declare(strict_types = 1);

namespace Elie\Validator;

use Elie\Validator\Rule\RuleInterface;

class Validator implements ValidatorInterface
{

/**
* Context to be validated.
* @var array
*/
protected $context = [];

/**
* Validated coontext.
* @var array
*/
protected $validatedContext = [];

/**
* Rules that validate context.
* @var array
*/
protected $rules = [];

/**
* Defaults to false, meaning that validation
* won't stop when an error is encountered.
* @var bool
*/
protected $stopOnError = false;

/**
* Contains the error(s) found during rules validation.
* @var array
*/
protected $errors = [];

public function __construct(array $context, bool $stopOnError = false)
{
$this->setContext($context);
$this->setStopOnError($stopOnError);
}

public function setContext(array $context): self
{
$this->context = $context;
return $this;
}

public function getValidatedContext(): array
{
return $this->validatedContext;
}

public function setRules(array $rules):self
{
$this->rules = [];
foreach ($rules as $rule) {
// The first element must be the key context
$key = $rule[0];
// The second element must be the class valdiator name
$class = $rule[1];
$this->rules[] = new $class($key, $this->get($key), $rule);
}
// Keep chaining
return $this;
}

public function getRules(): array
{
return $this->rules;
}

public function getErrors(): array
{
return $this->errors;
}

public function get(string $key)
{
return $this->context[$key] ?? null;
}

public function shouldStopOnError(): bool
{
return $this->stopOnError;
}

public function setStopOnError(bool $stopOnError): self
{
$this->stopOnError = $stopOnError;

return $this;
}

public function validate(): bool
{
$this->validatedContext = [];

// All rules supposed OK
$res = true;
$this->errors = [];

foreach ($this->rules as $rule) {
/* @var $rule RuleInterface */
if ($rule->validate() !== RuleInterface::ERROR) {
$this->validatedContext[$rule->getKey()] = $rule->getValue();
continue;
}

$this->errors[] = $rule->getError();
$res = false;

if ($this->stopOnError) {
return $res;
}
}

return $res;
}
}
4 changes: 3 additions & 1 deletion src/ValidatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ public function shouldStopOnError(): bool;

/**
* Change stopOnError value.
*
* @return ValidatorInterface
*/
public function setStopOnError(bool $stopOnError);

Expand All @@ -103,5 +105,5 @@ public function setStopOnError(bool $stopOnError);
*
* @return bool
*/
public function valdiate(): bool;
public function validate(): bool;
}
84 changes: 84 additions & 0 deletions tests/ValidatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types = 1);

namespace Elie\Validator;

use Elie\Validator\Rule\NumericRule;
use Elie\Validator\Rule\StringRule;
use PHPUnit\Framework\TestCase;

class ValidatorTest extends TestCase
{

public function testValidatedContext(): void
{
$validator = new Validator(['name' => 'Ben ']);

$rule = ['name', StringRule::class, 'min' => 3, 'max' => 30];

$validator->setRules([$rule]);

$res = $validator->validate();
assertThat($res, is(true));

$validatedContext = $validator->getValidatedContext();
assertThat($validatedContext, anArray(['name' => 'Ben']));

$value = $validator->get('name');
assertThat($value, identicalTo('Ben '));

$value = $validator->get('age');
assertThat($value, nullValue());

$rules = $validator->getRules();
assertThat($rules[0], anInstanceOf(StringRule::class));

assertThat($validator->shouldStopOnError(), is(false));
}

/**
* @dataProvider getValidatorProvider
*/
public function testValidate($context, $rules, $expectedResult, $errorsSize): void
{
$validator = new Validator($context);
$validator->setRules($rules);

$res = $validator->validate();

assertThat($res, identicalTo($expectedResult));
assertThat($validator->getErrors(), arrayWithSize($errorsSize));
}

public function getValidatorProvider(): \Generator
{
yield 'Age and name are valid' => [
// context
[
'age' => 25,
'name' => 'Ben'
],
// rules
[
['age', NumericRule::class, 'min' => 5, 'max' => 65],
['name', StringRule::class, 'min' => 3, 'max' => 30],
],
// expectedResult
true,
// $errorsSize
0
];

yield 'Age is not valid' => [
[
'age' => 25,
],
[
['age', NumericRule::class, 'min' => 26, 'max' => 65],
],
false,
1
];
}
}

0 comments on commit c6199c0

Please sign in to comment.