Skip to content

Commit

Permalink
Merge pull request #20 from tflori/feature/invokable
Browse files Browse the repository at this point in the history
make validator and filter invokable
  • Loading branch information
tflori authored Apr 15, 2018
2 parents c2ec67e + d2c8d8e commit 7aa07a8
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 30 deletions.
8 changes: 5 additions & 3 deletions src/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ public function filter($value, array $context = [])
} catch (InvalidValue $e) {
$this->filterFailed = true;
$this->errors = $e->errors;
return $value;
break;
}
}

Expand All @@ -291,12 +291,14 @@ public function filter($value, array $context = [])
*/
public function validate($value, array $context = [])
{
$filtered = $this->filter($value, $context);

if ($this->filterFailed) {
return false;
}

try {
$hash = md5(serialize([$value, $context]));
$hash = md5(serialize([$filtered, $context]));
if (isset($this->validationCache[$hash])) {
return $this->validationCache[$hash];
}
Expand All @@ -308,7 +310,7 @@ public function validate($value, array $context = [])
$valid = true;
$this->errors = [];
foreach ($this->validators as $validator) {
if (!$validator->validate($value, $context)) {
if (!$validator->validate($filtered, $context)) {
$valid = false;
if ($error = $validator->getError()) {
$this->errors[] = $error;
Expand Down
15 changes: 14 additions & 1 deletion src/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static function getFilter($filter)
{
if (is_string($filter)) {
$filter = Filter::fromString($filter);
} elseif (is_callable($filter)) {
} elseif (is_callable($filter) && !$filter instanceof FilterInterface) {
$filter = new Filter\Callback($filter);
}

Expand Down Expand Up @@ -81,6 +81,19 @@ public static function __callStatic($name, array $arguments)
return static::create(ucfirst($name), $arguments);
}

/**
* Call the filter is an alias for filter
*
* @param mixed $value
* @param array $context
* @return mixed
*/
public function __invoke($value, array $context = [])
{
return $this->filter($value, $context);
}


/**
* Create a filter dynamically
*
Expand Down
9 changes: 9 additions & 0 deletions src/FilterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ interface FilterInterface
*/
public function filter($value, array $context = []);

/**
* Call the filter is an alias for filter
*
* @param mixed $value
* @param array $context
* @return mixed
*/
public function __invoke($value, array $context = []);

/**
* Assign filter to $field
*
Expand Down
21 changes: 14 additions & 7 deletions src/Gate.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ public function getData(string $key = null, $validate = true)

$result = [];
foreach ($fields as $k => $field) {
$filtered = $field->filter(isset($this->rawData[$k]) ? $this->rawData[$k] : null, $this->rawData);
$filtered = $field->filter($this->rawData[$k] ?? null, $this->rawData);

if ($validate && !$field->validate($filtered, $this->rawData)) {
if ($validate && !$field->validate($this->rawData[$k] ?? null, $this->rawData)) {
if ($field->isRequired()) {
$errors = $field->getErrors();
if (count($errors) > 0) {
Expand All @@ -239,8 +239,9 @@ public function getData(string $key = null, $validate = true)
*
* @param string $key
* @return mixed
* @see Gate::getData()
* @see Gate::getData()
* @codeCoverageIgnore trivial
* @throws InvalidValue
*/
public function get(string $key = null)
{
Expand All @@ -252,14 +253,21 @@ public function get(string $key = null)
*
* @param string $key
* @return mixed
* @see Gate::getData()
* @see Gate::getData()
* @codeCoverageIgnore trivial
* @throws InvalidValue
*/
public function __get(string $key)
{
return $this->getData($key);
}

/**
* Validate $data or previously stored data
*
* @param array $data
* @return bool
*/
public function validate(array $data = null)
{
if ($data) {
Expand All @@ -268,13 +276,12 @@ public function validate(array $data = null)

$valid = true;
$this->errors = [];
$filtered = $this->getData(null, false);
foreach ($this->fields as $key => $field) {
if (empty($filtered[$key]) && !$field->isRequired()) {
if (empty($this->rawData[$key]) && !$field->isRequired()) {
continue;
}

if (!$field->validate($filtered[$key], $this->rawData)) {
if (!$field->validate($this->rawData[$key] ?? null, $this->rawData)) {
$valid = false;
$this->errors[$key] = $field->getErrors();
}
Expand Down
14 changes: 13 additions & 1 deletion src/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static function getValidator($validator)
{
if (is_string($validator)) {
$validator = static::fromString($validator);
} elseif (is_callable($validator)) {
} elseif (is_callable($validator) && !$validator instanceof ValidatorInterface) {
$validator = new Validator\Callback($validator);
}

Expand Down Expand Up @@ -101,6 +101,18 @@ public static function __callStatic($name, array $arguments)
return static::create(ucfirst($name), $arguments);
}

/**
* Call the validator is an alias for validate
*
* @param mixed $value
* @param array $context
* @return bool
*/
public function __invoke($value, array $context = []): bool
{
return $this->validate($value, $context);
}

/**
* Create a validator dynamically
*
Expand Down
9 changes: 9 additions & 0 deletions src/ValidatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ interface ValidatorInterface
*/
public function validate($value, array $context = []): bool;

/**
* Call the validator is an alias for validate
*
* @param mixed $value
* @param array $context
* @return bool
*/
public function __invoke($value, array $context = []): bool;

/**
* Assign validator to $field
*
Expand Down
17 changes: 17 additions & 0 deletions tests/Field/ValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,21 @@ public function resetsCacheWhenFiltersChange()
$field->addValidator('notEmpty');
$field->validate(' body ');
}

/** @test */
public function executesFilterBeforeValidation()
{
$field = \Mockery::mock(Field::class)->makePartial();
$validator = \Mockery::mock(NotEmpty::class)->makePartial();
$field->addValidator($validator);

$field->shouldReceive('filter')
->with('value', [])
->once()->andReturn(42);
$validator->shouldReceive('validate')
->with(42, [])
->once()->andReturn(true);

$field->validate('value');
}
}
19 changes: 19 additions & 0 deletions tests/Filter/CommonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Verja\Test\Filter;

use Verja\Filter\Trim;
use Verja\Test\TestCase;

class CommonTest extends TestCase
{
/** @test */
public function filterIsInvokable()
{
$filter = new Trim();

$result = $filter(' foo bar ');

self::assertSame('foo bar', $result);
}
}
6 changes: 3 additions & 3 deletions tests/Gate/GetDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function executesFilterOnField()
$gate->addField('username', $field);

$field->shouldReceive('filter')->with('john', ['username' => 'john', 'password' => 'abc123'])
->once()->andReturn('john');
->atLeast()->once()->andReturn('john');

$gate->getData();
}
Expand All @@ -50,10 +50,10 @@ public function executesValidateOnField()
{
$gate = new Gate([ 'username' => 'john@example', 'password' => 'abc123' ]);
$field = \Mockery::mock(Field::class)->makePartial();
$field->shouldReceive('filter')->andReturn('john');
$gate->addField('username', $field);

$field->shouldReceive('validate')->with('john', ['username' => 'john@example', 'password' => 'abc123'])
$field->shouldReceive('validate')
->with('john@example', ['username' => 'john@example', 'password' => 'abc123'])
->once()->andReturn(true);

$gate->getData();
Expand Down
15 changes: 0 additions & 15 deletions tests/Gate/ValidateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,6 @@ public function validatesEachField()
self::assertFalse($result);
}

/** @test */
public function usesFilteredValueForValidation()
{
$field = \Mockery::mock(Field::class)->makePartial();
$field->shouldReceive('filter')->with('value', [ 'f' => 'value' ])->once()->andReturn(42);
$field->shouldReceive('validate')->with(42, [ 'f' => 'value' ])->once()->andReturn(true);

$gate = new Gate([ 'f' => 'value' ]);
$gate->addField('f', $field);

$result = $gate->validate();

self::assertTrue($result);
}

/** @test */
public function validatesGivenArray()
{
Expand Down
19 changes: 19 additions & 0 deletions tests/Validator/CommonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Verja\Test\Validator;

use Verja\Test\TestCase;
use Verja\Validator\NotEmpty;

class CommonTest extends TestCase
{
/** @test */
public function validatorIsInvokable()
{
$validator = new NotEmpty();

$result = $validator('foo');

self::assertTrue($result);
}
}

0 comments on commit 7aa07a8

Please sign in to comment.