mirror of
https://github.com/Respect/Validation.git
synced 2024-06-01 13:22:24 +02:00
Make properties of "AbstractRelated" private
Following what is happening with pretty much every class in this library, this commit will make the public properties of "AbstractRelated" private. Because other objects use some of those public properties, this commit will also implement a couple of methods in "AbstractRelated" so they can access the values they need. This commit will also remove the method "decision" that makes dynamic calls to "assert()," "check()," and "validate()" methods. Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
parent
541fea9d7b
commit
051866f75a
|
@ -16,7 +16,6 @@ namespace Respect\Validation\Rules;
|
|||
use Respect\Validation\Exceptions\NestedValidationException;
|
||||
use Respect\Validation\Exceptions\ValidationException;
|
||||
use Respect\Validation\Validatable;
|
||||
use function is_null;
|
||||
use function is_scalar;
|
||||
|
||||
/**
|
||||
|
@ -30,17 +29,17 @@ abstract class AbstractRelated extends AbstractRule
|
|||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $mandatory = true;
|
||||
private $mandatory = true;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $reference = '';
|
||||
private $reference;
|
||||
|
||||
/**
|
||||
* @var Validatable|null
|
||||
*/
|
||||
public $validator;
|
||||
private $rule;
|
||||
|
||||
/**
|
||||
* @param mixed $input
|
||||
|
@ -57,20 +56,33 @@ abstract class AbstractRelated extends AbstractRule
|
|||
/**
|
||||
* @param mixed $reference
|
||||
*/
|
||||
public function __construct($reference, ?Validatable $validator = null, bool $mandatory = true)
|
||||
public function __construct($reference, ?Validatable $rule = null, bool $mandatory = true)
|
||||
{
|
||||
if (is_scalar($reference)) {
|
||||
$this->setName((string) $reference);
|
||||
if ($validator && !$validator->getName()) {
|
||||
$validator->setName((string) $reference);
|
||||
if ($rule && !$rule->getName()) {
|
||||
$rule->setName((string) $reference);
|
||||
}
|
||||
}
|
||||
|
||||
$this->reference = $reference;
|
||||
$this->validator = $validator;
|
||||
$this->rule = $rule;
|
||||
$this->mandatory = $mandatory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getReference()
|
||||
{
|
||||
return $this->reference;
|
||||
}
|
||||
|
||||
public function isMandatory(): bool
|
||||
{
|
||||
return $this->mandatory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -78,8 +90,8 @@ abstract class AbstractRelated extends AbstractRule
|
|||
{
|
||||
parent::setName($name);
|
||||
|
||||
if ($this->validator instanceof Validatable) {
|
||||
$this->validator->setName($name);
|
||||
if ($this->rule instanceof Validatable) {
|
||||
$this->rule->setName($name);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -95,8 +107,12 @@ abstract class AbstractRelated extends AbstractRule
|
|||
throw $this->reportError($input, ['hasReference' => false]);
|
||||
}
|
||||
|
||||
if ($this->rule === null || !$hasReference) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->decision('assert', $hasReference, $input);
|
||||
$this->rule->assert($this->getReferenceValue($input));
|
||||
} catch (ValidationException $validationException) {
|
||||
/** @var NestedValidationException $nestedValidationException */
|
||||
$nestedValidationException = $this->reportError($this->reference, ['hasReference' => true]);
|
||||
|
@ -116,7 +132,11 @@ abstract class AbstractRelated extends AbstractRule
|
|||
throw $this->reportError($input, ['hasReference' => false]);
|
||||
}
|
||||
|
||||
$this->decision('check', $hasReference, $input);
|
||||
if ($this->rule === null || !$hasReference) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->rule->check($this->getReferenceValue($input));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,16 +149,10 @@ abstract class AbstractRelated extends AbstractRule
|
|||
return false;
|
||||
}
|
||||
|
||||
return $this->decision('validate', $hasReference, $input);
|
||||
}
|
||||
if ($this->rule === null || !$hasReference) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $input
|
||||
*/
|
||||
private function decision(string $type, bool $hasReference, $input): bool
|
||||
{
|
||||
return (!$this->mandatory && !$hasReference)
|
||||
|| (is_null($this->validator)
|
||||
|| $this->validator->$type($this->getReferenceValue($input)));
|
||||
return $this->rule->validate($this->getReferenceValue($input));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@ use function property_exists;
|
|||
*/
|
||||
final class Attribute extends AbstractRelated
|
||||
{
|
||||
public function __construct(string $reference, ?Validatable $validator = null, bool $mandatory = true)
|
||||
public function __construct(string $reference, ?Validatable $rule = null, bool $mandatory = true)
|
||||
{
|
||||
parent::__construct($reference, $validator, $mandatory);
|
||||
parent::__construct($reference, $rule, $mandatory);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,7 @@ final class Attribute extends AbstractRelated
|
|||
*/
|
||||
public function getReferenceValue($input)
|
||||
{
|
||||
$propertyMirror = new ReflectionProperty($input, $this->reference);
|
||||
$propertyMirror = new ReflectionProperty($input, (string) $this->getReference());
|
||||
$propertyMirror->setAccessible(true);
|
||||
|
||||
return $propertyMirror->getValue($input);
|
||||
|
@ -51,6 +51,6 @@ final class Attribute extends AbstractRelated
|
|||
*/
|
||||
public function hasReference($input): bool
|
||||
{
|
||||
return is_object($input) && property_exists($input, $this->reference);
|
||||
return is_object($input) && property_exists($input, (string) $this->getReference());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,13 @@ final class Key extends AbstractRelated
|
|||
/**
|
||||
* @param mixed $reference
|
||||
*/
|
||||
public function __construct($reference, ?Validatable $referenceValidator = null, bool $mandatory = true)
|
||||
public function __construct($reference, ?Validatable $rule = null, bool $mandatory = true)
|
||||
{
|
||||
if (!is_scalar($reference) || $reference === '') {
|
||||
throw new ComponentException('Invalid array key name');
|
||||
}
|
||||
parent::__construct($reference, $referenceValidator, $mandatory);
|
||||
|
||||
parent::__construct($reference, $rule, $mandatory);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,7 +43,7 @@ final class Key extends AbstractRelated
|
|||
*/
|
||||
public function getReferenceValue($input)
|
||||
{
|
||||
return $input[$this->reference];
|
||||
return $input[$this->getReference()];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,6 +51,6 @@ final class Key extends AbstractRelated
|
|||
*/
|
||||
public function hasReference($input): bool
|
||||
{
|
||||
return is_array($input) && array_key_exists($this->reference, $input);
|
||||
return is_array($input) && array_key_exists($this->getReference(), $input);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ final class KeyNested extends AbstractRelated
|
|||
*/
|
||||
private function getReferencePieces(): array
|
||||
{
|
||||
return explode('.', rtrim((string) $this->reference, '.'));
|
||||
return explode('.', rtrim((string) $this->getReference(), '.'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,7 +65,7 @@ final class KeyNested extends AbstractRelated
|
|||
private function getValueFromArray(array $array, $key)
|
||||
{
|
||||
if (!array_key_exists($key, $array)) {
|
||||
$message = sprintf('Cannot select the key %s from the given array', $this->reference);
|
||||
$message = sprintf('Cannot select the key %s from the given array', $this->getReference());
|
||||
throw new ComponentException($message);
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ final class KeyNested extends AbstractRelated
|
|||
private function getValueFromArrayAccess(ArrayAccess $array, $key)
|
||||
{
|
||||
if (!$array->offsetExists($key)) {
|
||||
$message = sprintf('Cannot select the key %s from the given array', $this->reference);
|
||||
$message = sprintf('Cannot select the key %s from the given array', $this->getReference());
|
||||
throw new ComponentException($message);
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ final class KeyNested extends AbstractRelated
|
|||
private function getValueFromObject($object, string $property)
|
||||
{
|
||||
if (empty($property) || !property_exists($object, $property)) {
|
||||
$message = sprintf('Cannot select the property %s from the given object', $this->reference);
|
||||
$message = sprintf('Cannot select the property %s from the given object', $this->getReference());
|
||||
throw new ComponentException($message);
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ final class KeyNested extends AbstractRelated
|
|||
return $this->getValueFromObject($value, $key);
|
||||
}
|
||||
|
||||
$message = sprintf('Cannot select the property %s from the given data', $this->reference);
|
||||
$message = sprintf('Cannot select the property %s from the given data', $this->getReference());
|
||||
throw new ComponentException($message);
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ final class KeyNested extends AbstractRelated
|
|||
public function getReferenceValue($input)
|
||||
{
|
||||
if (is_scalar($input)) {
|
||||
$message = sprintf('Cannot select the %s in the given data', $this->reference);
|
||||
$message = sprintf('Cannot select the %s in the given data', $this->getReference());
|
||||
throw new ComponentException($message);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ final class KeySet extends AbstractWrapper
|
|||
*/
|
||||
private function getKeyReference(Key $rule)
|
||||
{
|
||||
return $rule->reference;
|
||||
return $rule->getReference();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,11 +87,11 @@ final class KeySet extends AbstractWrapper
|
|||
}
|
||||
|
||||
foreach ($this->keyRules as $keyRule) {
|
||||
if (!array_key_exists($keyRule->reference, $input) && $keyRule->mandatory) {
|
||||
if (!array_key_exists($keyRule->getReference(), $input) && $keyRule->isMandatory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unset($input[$keyRule->reference]);
|
||||
unset($input[$keyRule->getReference()]);
|
||||
}
|
||||
|
||||
return count($input) == 0;
|
||||
|
|
|
@ -1,213 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Respect/Validation.
|
||||
*
|
||||
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
*
|
||||
* For the full copyright and license information, please view the "LICENSE.md"
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Respect\Validation\Rules;
|
||||
|
||||
use Respect\Validation\Test\TestCase;
|
||||
use Respect\Validation\Validatable;
|
||||
|
||||
/**
|
||||
* @covers \Respect\Validation\Rules\AbstractRelated
|
||||
*
|
||||
* @author Emmerson Siqueira <emmersonsiqueira@gmail.com>
|
||||
* @author Gabriel Caruso <carusogabriel34@gmail.com>
|
||||
* @author Henrique Moody <henriquemoody@gmail.com>
|
||||
*/
|
||||
final class AbstractRelatedTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @return string[][]
|
||||
*/
|
||||
public function providerForOperations(): array
|
||||
{
|
||||
return [
|
||||
['validate'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function constructionOfAbstractRelatedClass(): void
|
||||
{
|
||||
$validatableMock = $this->createMock(Validatable::class);
|
||||
$relatedRuleMock = $this->getMockForAbstractClass(AbstractRelated::class, ['foo', $validatableMock]);
|
||||
|
||||
self::assertEquals('foo', $relatedRuleMock->getName());
|
||||
self::assertEquals('foo', $relatedRuleMock->reference);
|
||||
self::assertTrue($relatedRuleMock->mandatory);
|
||||
self::assertInstanceOf(Validatable::class, $relatedRuleMock->validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerForOperations
|
||||
*
|
||||
* @test
|
||||
*/
|
||||
public function operationsShouldReturnTrueWhenReferenceValidatesItsValue(string $method): void
|
||||
{
|
||||
$validatableMock = $this->createMock(Validatable::class);
|
||||
$validatableMock->expects(self::any())
|
||||
->method($method)
|
||||
->will(self::returnValue(true));
|
||||
|
||||
$relatedRuleMock = $this->getMockForAbstractClass(AbstractRelated::class, ['foo', $validatableMock]);
|
||||
$relatedRuleMock->expects(self::any())
|
||||
->method('hasReference')
|
||||
->will(self::returnValue(true));
|
||||
|
||||
self::assertTrue($relatedRuleMock->$method('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function validateShouldReturnFalseWhenIsMandatoryAndThereIsNoReference(): void
|
||||
{
|
||||
$relatedRuleMock = $this->getMockForAbstractClass(AbstractRelated::class, ['foo']);
|
||||
$relatedRuleMock->expects(self::any())
|
||||
->method('hasReference')
|
||||
->will(self::returnValue(false));
|
||||
|
||||
self::assertFalse($relatedRuleMock->validate('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAcceptReferenceOnConstructor(): void
|
||||
{
|
||||
$reference = 'something';
|
||||
|
||||
$abstractMock = $this
|
||||
->getMockBuilder(AbstractRelated::class)
|
||||
->setConstructorArgs([$reference])
|
||||
->getMock();
|
||||
|
||||
self::assertSame($reference, $abstractMock->reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeMandatoryByDefault(): void
|
||||
{
|
||||
$abstractMock = $this
|
||||
->getMockBuilder(AbstractRelated::class)
|
||||
->setConstructorArgs(['something'])
|
||||
->getMock();
|
||||
|
||||
self::assertTrue($abstractMock->mandatory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAcceptReferenceAndRuleOnConstructor(): void
|
||||
{
|
||||
$ruleMock = $this->createMock(Validatable::class);
|
||||
|
||||
$abstractMock = $this
|
||||
->getMockBuilder(AbstractRelated::class)
|
||||
->setConstructorArgs(['something', $ruleMock])
|
||||
->getMock();
|
||||
|
||||
self::assertSame($ruleMock, $abstractMock->validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldDefineRuleNameAsReferenceWhenRuleDoesNotHaveName(): void
|
||||
{
|
||||
$reference = 'something';
|
||||
|
||||
$ruleMock = $this->createMock(Validatable::class);
|
||||
$ruleMock
|
||||
->expects(self::at(0))
|
||||
->method('getName')
|
||||
->will(self::returnValue(null));
|
||||
$ruleMock
|
||||
->expects(self::at(1))
|
||||
->method('setName')
|
||||
->with($reference);
|
||||
|
||||
$abstractMock = $this
|
||||
->getMockBuilder(AbstractRelated::class)
|
||||
->setConstructorArgs(['something', $ruleMock])
|
||||
->getMock();
|
||||
|
||||
self::assertSame($ruleMock, $abstractMock->validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotDefineRuleNameAsReferenceWhenRuleDoesHaveName(): void
|
||||
{
|
||||
$ruleMock = $this->createMock(Validatable::class);
|
||||
$ruleMock
|
||||
->expects(self::at(0))
|
||||
->method('getName')
|
||||
->will(self::returnValue('something else'));
|
||||
$ruleMock
|
||||
->expects(self::never())
|
||||
->method('setName');
|
||||
|
||||
$abstractMock = $this
|
||||
->getMockBuilder(AbstractRelated::class)
|
||||
->setConstructorArgs(['something', $ruleMock])
|
||||
->getMock();
|
||||
|
||||
self::assertSame($ruleMock, $abstractMock->validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAcceptMandatoryFlagOnConstructor(): void
|
||||
{
|
||||
$mandatory = false;
|
||||
|
||||
$abstractMock = $this
|
||||
->getMockBuilder(AbstractRelated::class)
|
||||
->setConstructorArgs(['something', $this->createMock(Validatable::class), $mandatory])
|
||||
->getMock();
|
||||
|
||||
self::assertFalse($abstractMock->mandatory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldDefineChildNameWhenDefiningTheNameOfTheParent(): void
|
||||
{
|
||||
$name = 'My new name';
|
||||
$ruleMock = $this->createMock(Validatable::class);
|
||||
$ruleMock
|
||||
->expects(self::at(0))
|
||||
->method('getName')
|
||||
->will(self::returnValue('something else'));
|
||||
$ruleMock
|
||||
->expects(self::at(1))
|
||||
->method('setName')
|
||||
->with($name);
|
||||
|
||||
$this
|
||||
->getMockBuilder(AbstractRelated::class)
|
||||
->setConstructorArgs(['something', $ruleMock])
|
||||
->getMock();
|
||||
|
||||
$ruleMock->setName($name);
|
||||
}
|
||||
}
|
|
@ -18,8 +18,9 @@ use Respect\Validation\Validatable;
|
|||
use stdClass;
|
||||
|
||||
/**
|
||||
* @group rule
|
||||
* @covers \Respect\Validation\Exceptions\AttributeException
|
||||
* @group rule
|
||||
*
|
||||
* @covers \Respect\Validation\Rules\AbstractRelated
|
||||
* @covers \Respect\Validation\Rules\Attribute
|
||||
*
|
||||
* @author Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
|
|
|
@ -19,8 +19,9 @@ use Respect\Validation\Validatable;
|
|||
use stdClass;
|
||||
|
||||
/**
|
||||
* @group rule
|
||||
* @covers \Respect\Validation\Exceptions\KeyNestedException
|
||||
* @group rule
|
||||
*
|
||||
* @covers \Respect\Validation\Rules\AbstractRelated
|
||||
* @covers \Respect\Validation\Rules\KeyNested
|
||||
*
|
||||
* @author Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
|
|
|
@ -17,8 +17,9 @@ use Respect\Validation\Test\TestCase;
|
|||
use Throwable;
|
||||
|
||||
/**
|
||||
* @group rule
|
||||
* @covers \Respect\Validation\Exceptions\KeyException
|
||||
* @group rule
|
||||
*
|
||||
* @covers \Respect\Validation\Rules\AbstractRelated
|
||||
* @covers \Respect\Validation\Rules\Key
|
||||
*
|
||||
* @author Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
|
|
Loading…
Reference in a new issue