Skip to content

Commit

Permalink
Merge pull request #29 from Icinga/run-validators-irrespective-of-an-…
Browse files Browse the repository at this point in the history
…empty-value

Run validators irrespective of an empty value
  • Loading branch information
nilmerg authored Mar 21, 2023
2 parents 963bd07 + bee9137 commit 2273606
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 115 deletions.
39 changes: 0 additions & 39 deletions src/BaseValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,4 @@
abstract class BaseValidator implements Validator
{
use Messages;

/** @var bool Whether to validate an empty value */
protected $validateEmpty = false;

/**
* Get whether to validate an empty value
*
* @return bool
*/
public function validateEmpty(): bool
{
return $this->validateEmpty;
}

/**
* Set whether to validate an empty value
*
* @param bool $validateEmpty
*
* @return $this
*/
public function setValidateEmpty(bool $validateEmpty = true): self
{
$this->validateEmpty = $validateEmpty;

return $this;
}

/**
* Get whether the given value is empty
*
* @param mixed $value
*
* @return bool
*/
public function isEmpty($value): bool
{
return $value === '' || $value === [] || $value === null;
}
}
2 changes: 0 additions & 2 deletions src/CallbackValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
*/
class CallbackValidator extends BaseValidator
{
protected $validateEmpty = true;

/** @var callable Validation callback */
protected $callback;

Expand Down
16 changes: 1 addition & 15 deletions src/ValidatorChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function addValidators($validators)

foreach ($validators as $name => $validator) {
$breakChainOnFailure = false;
$validateEmpty = null;

if (! $validator instanceof Validator) {
if (is_int($name)) {
if (! is_array($validator)) {
Expand Down Expand Up @@ -130,19 +130,9 @@ public function addValidators($validators)

unset($validator['break_chain_on_failure']);
}

if (isset($validator['validate_empty'])) {
$validateEmpty = $validator['validate_empty'];

unset($validator['validate_empty']);
}
}

$validator = $this->createValidator($name, $validator);

if ($validateEmpty !== null && $validator instanceof BaseValidator) {
$validator->setValidateEmpty($validateEmpty);
}
}

$this->add($validator, $breakChainOnFailure);
Expand Down Expand Up @@ -276,10 +266,6 @@ public function isValid($value)
$valid = true;

foreach ($this as $validator) {
if ($validator instanceof BaseValidator && ! $validator->validateEmpty() && $validator->isEmpty($value)) {
continue;
}

if ($validator->isValid($value)) {
continue;
}
Expand Down
75 changes: 16 additions & 59 deletions tests/ValidatorChainTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
namespace ipl\Tests\Validator;

use InvalidArgumentException;
use ipl\I18n\NoopTranslator;
use ipl\I18n\StaticTranslator;
use ipl\Validator\CallbackValidator;
use ipl\Validator\ValidatorChain;
use LogicException;

class ValidatorChainTest extends TestCase
{
Expand Down Expand Up @@ -215,63 +214,6 @@ public function testIsValidWithValidatorThatBreaksTheChain()
$this->assertSame(['Validation failed'], $validators->getMessages());
}

public function testValidateEmptyFlag()
{
$validators = (new ValidatorChain())
->addValidators([
new CallbackValidator(function ($value, CallbackValidator $validator) {
$validator->addMessage('This validator should get called');
return false;
})
]);

$this->assertFalse($validators->isValid(null));
$this->assertSame(['This validator should get called'], $validators->getMessages());

$validators = (new ValidatorChain())
->addValidators([
(new CallbackValidator(function ($value, CallbackValidator $validator) {
$validator->addMessage('This validator should not get called');
return false;
}))
->setValidateEmpty(false)
]);

$this->assertTrue($validators->isValid(null));
$this->assertSame([], $validators->getMessages());

$validators = (new ValidatorChain())
->addValidators(['DateTime' => null]);

$this->assertTrue($validators->isValid(null));
$this->assertSame([], $validators->getMessages());

StaticTranslator::$instance = new NoopTranslator();
$validators = (new ValidatorChain())
->addValidators(['DateTime' => ['validate_empty' => true]]);

$this->assertFalse($validators->isValid(null));
$this->assertSame(['Invalid date/time given.'], $validators->getMessages());
}

public function testOnlyEmptyValuesAreSkippedIfValidateEmptyIsFalse()
{
$validators = (new ValidatorChain())
->addValidators([
(new CallbackValidator(function () {
return false;
}))->setValidateEmpty(false)
]);

$this->assertFalse($validators->isValid('0'), "`'0'` is not validated");
$this->assertFalse($validators->isValid(0), '`0` is not validated');
$this->assertFalse($validators->isValid(false), '`false` is not validated');

$this->assertTrue($validators->isValid(null), '`null` is validated');
$this->assertTrue($validators->isValid(''), "'' is validated");
$this->assertTrue($validators->isValid([]), '`[]` is validated');
}

public function testIsValidClearsMessages()
{
$validators = (new ValidatorChain())
Expand Down Expand Up @@ -356,4 +298,19 @@ public function testNameToOptionsSpecExceptionIfClassDoesNotExist()

(new ValidatorChain())->addValidators($spec);
}

public function testValidatorsWithoutSupportForEmptyValuesThrow()
{
$this->expectException(LogicException::class);
$this->expectExceptionMessage('This is expected');

$chain = (new ValidatorChain())
->add(new CallbackValidator(function ($value) {
if ($value === null) {
throw new LogicException('This is expected');
}
}));

$chain->isValid(null);
}
}

0 comments on commit 2273606

Please sign in to comment.