Major refactoring. Removed a layer from the validator rules, now all of them have a single level. Simplified fluent interface (chains and static validators), improved folder organization.

This commit is contained in:
Alexandre Gomes Gaigalas 2010-09-26 02:16:02 -03:00
parent 85f4843df7
commit b43371315a
21 changed files with 110 additions and 127 deletions

View file

@ -1,8 +0,0 @@
<?php
namespace Respect\Validation;
class ComponentException extends \Exception
{
}

View file

@ -1,8 +0,0 @@
<?php
namespace Respect\Validation\Date;
class OutOfBoundsException extends \OutOfBoundsException
{
}

View file

@ -0,0 +1,10 @@
<?php
namespace Respect\Validation\Exceptions;
use Exception;
class ComponentException extends Exception
{
}

View file

@ -0,0 +1,10 @@
<?php
namespace Respect\Validation\Exceptions;
use OutOfBoundsException;
class DateOutOfBoundsException extends OutOfBoundsException
{
}

View file

@ -0,0 +1,10 @@
<?php
namespace Respect\Validation\Exceptions;
use LengthException;
class EmptyStringException extends LengthException
{
}

View file

@ -1,6 +1,6 @@
<?php
namespace Respect\Validation;
namespace Respect\Validation\Exceptions;
use InvalidArgumentException;
use Exception;

View file

@ -1,8 +1,14 @@
<?php
namespace Respect\Validation;
namespace Respect\Validation\Rules;
abstract class AbstractCompositeRule extends AbstractRule implements Validatable
use Respect\Validation\Validatable;
use Respect\Validation\Validator;
use Respect\Validation\Rules\AbstractRule;
use Respect\Validation\Exceptions\ComponentException;
use Respect\Validation\Exceptions\InvalidException;
abstract class AbstractComposite extends AbstractRule implements Validatable
{
protected $rules = array();

View file

@ -1,11 +1,11 @@
<?php
namespace Respect\Validation\Date;
namespace Respect\Validation\Rules;
use Respect\Validation\AbstractRule;
use DateTime;
use Respect\Validation\Rules\AbstractRule;
abstract class AbstractDateValidator extends AbstractRule
abstract class AbstractDate extends AbstractRule
{
protected $format = DateTime::RFC1036;

View file

@ -1,6 +1,6 @@
<?php
namespace Respect\Validation;
namespace Respect\Validation\Rules;
abstract class AbstractRule
{

View file

@ -1,12 +1,11 @@
<?php
namespace Respect\Validation\Composite;
namespace Respect\Validation\Rules;
use Respect\Validation\AbstractCompositeRule;
use Respect\Validation\InvalidException;
use Respect\Validation\Exceptions\InvalidException;
use Respect\Validation\Validatable;
class All extends AbstractCompositeRule implements Validatable
class All extends AbstractComposite implements Validatable
{
public function validate($input)

View file

@ -1,11 +1,13 @@
<?php
namespace Respect\Validation\Date;
namespace Respect\Validation\Rules;
use Respect\Validation\Validatable;
use Respect\Validation\ComponentException;
use Respect\Validation\Rules\AbstractDate;
use Respect\Validation\Exceptions\ComponentException;
use Respect\Validation\Exceptions\DateOutOfBoundsException;
class Between extends AbstractDateValidator implements Validatable
class DateBetween extends AbstractDate implements Validatable
{
const MSG_OUT_OF_BOUNDS = 'Date_Between_1';
@ -33,7 +35,7 @@ class Between extends AbstractDateValidator implements Validatable
{
$target = $this->getDateObject($input);
if (!$this->validate($target))
throw new OutOfBoundsException(
throw new DateOutOfBoundsException(
sprintf(
$this->getMessage(self::MSG_OUT_OF_BOUNDS),
$this->formatDate($target), $this->formatDate($this->min),

View file

@ -1,12 +1,11 @@
<?php
namespace Respect\Validation\Composite;
namespace Respect\Validation\Rules;
use Respect\Validation\AbstractCompositeRule;
use Respect\Validation\InvalidException;
use Respect\Validation\Exceptions\InvalidException;
use Respect\Validation\Validatable;
class One extends AbstractCompositeRule implements Validatable
class One extends AbstractComposite implements Validatable
{
public function assert($input)

View file

@ -1,11 +1,12 @@
<?php
namespace Respect\Validation\String;
namespace Respect\Validation\Rules;
use Respect\Validation\Validatable;
use Respect\Validation\AbstractRule;
use Respect\Validation\Exceptions\EmptyStringException;
use Respect\Validation\Rules\AbstractRule;
class NotEmpty extends AbstractRule implements Validatable
class StringNotEmpty extends AbstractRule implements Validatable
{
const MSG_EMPTY_STRING = 'String_NotEmpty_1';

View file

@ -1,8 +0,0 @@
<?php
namespace Respect\Validation\String;
class EmptyStringException extends \LengthException
{
}

View file

@ -2,21 +2,16 @@
namespace Respect\Validation;
use Respect\Validation\Composite\All;
use Respect\Validation\Rules\All;
use ReflectionClass;
use Respect\Validation\ComponentException;
class Validator extends All
{
protected $subject;
protected $ruleName;
protected $arguments = array();
public function getSubject()
{
return $this->subject;
}
public function getRuleName()
{
return $this->ruleName;
@ -27,11 +22,6 @@ class Validator extends All
return $this->arguments;
}
public function setSubject($subject)
{
$this->subject = $subject;
}
public function setRuleName($ruleName)
{
$this->ruleName = $ruleName;
@ -56,10 +46,6 @@ class Validator extends All
protected function applyParts($parts)
{
foreach ($parts as $a) {
if (!isset($this->subject)) {
$this->setSubject($a);
continue;
}
if (!isset($this->ruleName)) {
$this->setRuleName($a);
continue;
@ -78,23 +64,18 @@ class Validator extends All
protected function checkForCompleteRule()
{
if (!isset($this->subject, $this->ruleName))
if (!isset($this->ruleName))
return;
$this->addRule(
static::buildRule(
array($this->subject, $this->ruleName), $this->arguments
)
static::buildRule($this->ruleName, $this->arguments)
);
$this->subject = null;
$this->ruleName = null;
$this->arguments = array();
}
public static function __callStatic($subject, $arguments)
public static function __callStatic($ruleName, $arguments)
{
$ruleName = array_shift($arguments);
$validator = new static;
$validator->setSubject($subject);
$validator->setRuleName($ruleName);
$validator->setArguments($arguments);
$validator->checkForCompleteRule();
@ -113,9 +94,8 @@ class Validator extends All
);
$validatorFqn = explode('\\', get_called_class());
array_pop($validatorFqn);
if (!is_array($ruleSpec))
$ruleSpec = explode('\\', $ruleSpec);
$validatorFqn = array_merge($validatorFqn, $ruleSpec);
$validatorFqn[] = 'Rules';
$validatorFqn[] = $ruleSpec;
$validatorFqn = array_map('ucfirst', $validatorFqn);
$validatorFqn = implode('\\', $validatorFqn);
$validatorClass = new ReflectionClass($validatorFqn);

View file

@ -2,7 +2,7 @@
namespace Respect\Validation;
class AbstractCompositeRuleTest extends ValidatorTestCase
class AbstractCompositeTest extends ValidatorTestCase
{
protected $object;
@ -10,7 +10,7 @@ class AbstractCompositeRuleTest extends ValidatorTestCase
protected function setUp()
{
$this->object = $this->getMockForAbstractClass(
'Respect\Validation\AbstractCompositeRule'
'Respect\Validation\Rules\AbstractComposite'
);
}
@ -29,7 +29,7 @@ class AbstractCompositeRuleTest extends ValidatorTestCase
}
/**
* @expectedException Respect\Validation\ComponentException
* @expectedException Respect\Validation\Exceptions\ComponentException
*/
public function testAddNonValidator()
{
@ -37,17 +37,17 @@ class AbstractCompositeRuleTest extends ValidatorTestCase
}
/**
* @expectedException Respect\Validation\ComponentException
* @expectedException Respect\Validation\Exceptions\ComponentException
*/
public function testAddNonValidator2()
{
if (!class_exists('Respect\Validation\Foo\Freak', false)) {
if (!class_exists('Respect\Validation\FooFreak', false)) {
eval("
namespace Respect\Validation\Foo;
class Freak{}
namespace Respect\Validation\Rules;
class FooFreak{}
");
}
$this->object->addRule('Foo\Freak');
$this->object->addRule('FooFreak');
}
/**
@ -71,19 +71,20 @@ class AbstractCompositeRuleTest extends ValidatorTestCase
{
$this->providerForMockImpossibleValidators();
$this->object->addRules(array(
'Foo\Bar', 'Foo\Baz', 'Foo\Bat' => array(1, 2, 3)
'FooBar', 'FooBaz', 'FooBat' => array(1, 2, 3)
));
$this->assertValidatorPresence($this->object, 'Bar', 'Baz', 'Bat');
$this->assertValidatorPresence($this->object, 'FooBar', 'FooBaz',
'FooBat');
}
/**
* @expectedException Respect\Validation\ComponentException
* @expectedException Respect\Validation\Exceptions\ComponentException
*/
public function testBuildValidatorsInvalid()
{
$this->providerForMockImpossibleValidators();
$this->object->addRules(array(
'Foo\Bar', 'Foo\Baz', 'Foo\Bat' => 'balkbal'
'FooBar', 'FooBaz', 'FooBat' => 'balkbal'
));
}

View file

@ -1,9 +1,9 @@
<?php
namespace Respect\Validation\Composite;
namespace Respect\Validation\Rules;
use Respect\Validation\ValidatorTestCase;
use Respect\Validation\InvalidException;
use Respect\Validation\Exceptions\InvalidException;
class AllTest extends ValidatorTestCase
{

View file

@ -1,10 +1,10 @@
<?php
namespace Respect\Validation\Date;
namespace Respect\Validation\Rules;
use DateTime;
class BetweenTest extends \PHPUnit_Framework_TestCase
class DateBetweenTest extends \PHPUnit_Framework_TestCase
{
/**
@ -12,31 +12,31 @@ class BetweenTest extends \PHPUnit_Framework_TestCase
*/
public function testBetweenValid($input, $min, $max)
{
$between = new Between($min, $max);
$between = new DateBetween($min, $max);
$this->assertTrue($between->validate($input));
$this->assertTrue($between->assert($input));
}
/**
* @dataProvider providerForInvalidDates
* @expectedException Respect\Validation\Date\OutOfBoundsException
* @expectedException Respect\Validation\Exceptions\DateOutOfBoundsException
*/
public function testBetweenInvalid($input, $min, $max)
{
$between = new Between($min, $max);
$between = new DateBetween($min, $max);
$this->assertFalse($between->validate($input));
$this->assertFalse($between->assert($input));
}
/**
* @dataProvider providerForInvalidConfigs
* @expectedException Respect\Validation\ComponentException
* @expectedException Respect\Validation\Exceptions\ComponentException
*/
public function testInvalidConfigs($min, $max)
{
$between = new Between($min, $max);
$between = new DateBetween($min, $max);
}
public function providerForValidDates()

View file

@ -1,9 +1,9 @@
<?php
namespace Respect\Validation\Composite;
namespace Respect\Validation\Rules;
use Respect\Validation\ValidatorTestCase;
use Respect\Validation\InvalidException;
use Respect\Validation\Exceptions\InvalidException;
class OneTest extends ValidatorTestCase
{

View file

@ -5,67 +5,54 @@ namespace Respect\Validation;
class ValidatorTest extends ValidatorTestCase
{
public function testPartialEmpty()
{
$v = Validator::date();
$this->assertType('Respect\Validation\Validator', $v);
$this->assertSame('date', $v->getSubject());
}
public function testPartialInputSubject()
{
$v = Validator::date('between', 'yesterday', 'tomorrow');
$v = Validator::dateBetween('yesterday', 'tomorrow');
$this->assertType('Respect\Validation\Validator', $v);
$this->assertEquals(1, count($v->getRules()));
$this->assertNull($v->getSubject());
$this->assertNull($v->getRuleName());
$this->assertEquals(array(), $v->getArguments());
}
public function testPartialInputChain()
{
$v = Validator::date()->between('yesterday', 'tomorrow')
->string('notEmpty');
$v = Validator::dateBetween('yesterday', 'tomorrow')->stringNotEmpty();
$this->assertType('Respect\Validation\Validator', $v);
$this->assertEquals(2, count($v->getRules()));
$this->assertNull($v->getSubject());
$this->assertNull($v->getRuleName());
$this->assertEquals(array(), $v->getArguments());
}
public function testValidateSimple()
{
$v = Validator::string('notEmpty')->validate('foo');
$v = Validator::stringNotEmpty()->validate('foo');
$this->assertTrue($v);
}
public function testValidateArguments()
{
$v = Validator::date('between', 'yesterday', 'tomorrow')
->validate('now');
$v = Validator::dateBetween('yesterday', 'tomorrow')->validate('now');
$this->assertTrue($v);
}
public function testValidateFluent()
{
$v = Validator::date()->between('yesterday', 'tomorrow')
->validate('now');
$v = Validator::dateBetween('yesterday', 'tomorrow')->validate('now');
$this->assertTrue($v);
}
public function testValidateFluentChain()
{
$v = Validator::date()->between('yesterday', 'tomorrow')
->string('notEmpty')
$v = Validator::dateBetween('yesterday', 'tomorrow')->stringNotEmpty()
->assert('now');
$this->assertTrue($v);
}
public function testValidatorComposite()
{
$v = Validator::composite()->one(
Validator::string()->notEmpty,
Validator::date()->between('+2 years', '+3 years')
$v = Validator::one(
Validator::stringNotEmpty(),
Validator::dateBetween('+2 years', '+3 years')
)->validate('now');
$this->assertTrue($v);
}

View file

@ -3,6 +3,7 @@
namespace Respect\Validation;
use Mockery;
use Respect\Validation\Exceptions\InvalidException;
abstract class ValidatorTestCase extends \PHPUnit_Framework_TestCase
{
@ -13,7 +14,7 @@ abstract class ValidatorTestCase extends \PHPUnit_Framework_TestCase
array_shift($args);
foreach ($args as $req) {
$this->assertTrue(
$validator->hasRule('Respect\Validation\Foo\\' . $req)
$validator->hasRule('Respect\Validation\Rules\\' . $req)
);
}
}
@ -33,10 +34,10 @@ abstract class ValidatorTestCase extends \PHPUnit_Framework_TestCase
$validator->shouldReceive('getMessages')->andReturn(
$messages
);
$className = 'Respect\Validation\Foo\\' . $name;
$className = 'Respect\Validation\Rules\\' . $name;
if (!class_exists($className, false)) {
eval("
namespace Respect\Validation\Foo;
namespace Respect\Validation\Rules;
class $name implements \Respect\Validation\Validatable {
public function assert(\$input) {}
public function validate(\$input) {}
@ -55,13 +56,13 @@ abstract class ValidatorTestCase extends \PHPUnit_Framework_TestCase
public function providerForMockImpossibleValidators()
{
$firstValidator = $this->buildMockValidator(
'Bar', array('Bar_1' => 'fga', 'Bar_2' => 'dfgb'), true
'FooBar', array('Bar_1' => 'fga', 'Bar_2' => 'dfgb'), true
);
$secondValidator = $this->buildMockValidator(
'Baz', array('Baz_1' => 'gedg', 'Baz_2' => 'rihg49'), true
'FooBaz', array('Baz_1' => 'gedg', 'Baz_2' => 'rihg49'), true
);
$thirdValidator = $this->buildMockValidator(
'Bat', array('Bat_1' => 'dfdsgdgfgb'), true
'FooBat', array('Bat_1' => 'dfdsgdgfgb'), true
);
return array(
array($firstValidator, $secondValidator, $thirdValidator),
@ -73,13 +74,14 @@ abstract class ValidatorTestCase extends \PHPUnit_Framework_TestCase
public function providerForMockValidators()
{
$firstValidator = $this->buildMockValidator(
'Bara', array('Bara_1' => 'fga', 'Bara_2' => 'dfgb'), false
'FooBara', array('Bara_1' => 'fga', 'Bara_2' => 'dfgb'), false
);
$secondValidator = $this->buildMockValidator(
'Baza', array('Baza_1' => 'gedg', 'Baza_2' => 'rihg49'), false
'FooBaza', array('Baza_1' => 'gedg', 'Baza_2' => 'rihg49'),
false
);
$thirdValidator = $this->buildMockValidator(
'Bata', array('Bata_1' => 'dfdsgdgfgb'), false
'FooBata', array('Bata_1' => 'dfdsgdgfgb'), false
);
return array(
array($firstValidator, $secondValidator, $thirdValidator),