Create "Type" rule

This commit is contained in:
Henrique Moody 2015-02-02 10:50:17 -02:00
parent 6633ef3d3f
commit 4c4c3d4c25
5 changed files with 172 additions and 5 deletions

View file

@ -113,13 +113,13 @@ $usernameValidator->validate('#$%'); //false
* `Respect\Validation\Exceptions\NestedValidationExceptionInterface`:
* Use when calling `assert()`.
* Interface has three methods: `getFullMessage()`, `findMessages()`, and `getMainMessage()`.
* `Respect\Validation\Exceptions\ValidationExceptionInterface`:
* `Respect\Validation\Exceptions\ValidationExceptionInterface`:
* Use when calling `::check()`.
* All `Respect\Validation` validation exceptions implement this interface.
* All `Respect\Validation` validation exceptions implement this interface.
* Interface has one method: `getMainMessage()`;
* `Repect\Validation\Exceptions\ExceptionInterface`:
* All `Respect\Validation\Exceptions` implement this interface.
* `Repect\Validation\Exceptions\ExceptionInterface`:
* All `Respect\Validation\Exceptions` implement this interface.
### Informative Exceptions
When something goes wrong, Validation can tell you exactly what's going on. For this,
@ -228,6 +228,7 @@ Message:
* [v::object()](#vobject)
* [v::string()](#vstring)
* [v::true()](#vtrue)
* [v::type()](#vtypestring-type)
* [v::xdigit()](#vxdigit)
### Generics
@ -238,6 +239,7 @@ Message:
* [v::callback()](#vcallbackcallable-callback)
* [v::filterVar()](#vfiltervarint-filter)
* [v::not()](#vnotv-negatedvalidator)
* [v::type()](#vtypestring-type)
* [v::when()](#vwhenv-if-v-then-v-else)
### Comparing Values
@ -1935,6 +1937,26 @@ See also
* [v::false()](#vfalse)
#### v::type(string $type)
Validates the type of input.
```php
v::type('bool')->validate(true); //true
v::type('callable')->validate(function (){}); //true
v::type('object')->validate(new stdClass()); //true
```
See also
* [v::arr()](#varr)
* [v::bool()](#vbool)
* [v::float()](#vfloat)
* [v::instance()](#vinstancestring-instancename)
* [v::int()](#vint)
* [v::object()](#vobject)
* [v::string()](#vstring)
#### v::uploaded()
Validates if the given data is a file that was uploaded via HTTP POST.

View file

@ -0,0 +1,14 @@
<?php
namespace Respect\Validation\Exceptions;
class TypeException extends ValidationException
{
public static $defaultTemplates = array(
self::MODE_DEFAULT => array(
self::STANDARD => '{{name}} must be {{type}}',
),
self::MODE_NEGATIVE => array(
self::STANDARD => '{{name}} must not be {{type}}',
),
);
}

43
library/Rules/Type.php Normal file
View file

@ -0,0 +1,43 @@
<?php
namespace Respect\Validation\Rules;
use Respect\Validation\Exceptions\ComponentException;
class Type extends AbstractRule
{
public $type;
public $availableTypes = array(
'array' => 'array',
'bool' => 'boolean',
'boolean' => 'boolean',
'callable' => 'callable',
'double' => 'double',
'float' => 'double',
'int' => 'integer',
'integer' => 'integer',
'null' => 'NULL',
'object' => 'object',
'resource' => 'resource',
'string' => 'string',
);
public function __construct($type)
{
$lowerType = strtolower($type);
if (!isset($this->availableTypes[$lowerType])) {
throw new ComponentException(sprintf('"%s" is not a valid type', print_r($type, true)));
}
$this->type = $type;
}
public function validate($input)
{
$lowerType = strtolower($this->type);
if ('callable' === $lowerType) {
return is_callable($input);
}
return ($this->availableTypes[$lowerType] === gettype($input));
}
}

View file

@ -92,6 +92,7 @@ use Respect\Validation\Rules\AllOf;
* @method static Validator symbolicLink()
* @method static Validator tld()
* @method static Validator true()
* @method static Validator type(string $type)
* @method static Validator uploaded()
* @method static Validator uppercase()
* @method static Validator url()

87
tests/Rules/TypeTest.php Normal file
View file

@ -0,0 +1,87 @@
<?php
namespace Respect\Validation\Rules;
use stdClass;
class TypeTest extends \PHPUnit_Framework_TestCase
{
public function testShouldDefineTypeOnConstructor()
{
$type = 'int';
$rule = new Type($type);
$this->assertSame($type, $rule->type);
}
public function testShouldNotBeCaseSensitive()
{
$rule = new Type('InTeGeR');
$this->assertTrue($rule->validate(42));
}
/**
* @expectedException Respect\Validation\Exceptions\ComponentException
* @expectedExceptionMessage "whatever" is not a valid type
*/
public function testShouldThrowExceptionWhenTypeIsNotValid()
{
new Type('whatever');
}
/**
* @dataProvider providerForValidType
*/
public function testShouldValidateValidTypes($type, $input)
{
$rule = new Type($type);
$this->assertTrue($rule->validate($input));
}
/**
* @dataProvider providerForInvalidType
*/
public function testShouldNotValidateInvalidTypes($type, $input)
{
$rule = new Type($type);
$this->assertFalse($rule->validate($input));
}
/**
* @expectedException Respect\Validation\Exceptions\TypeException
* @expectedExceptionMessage "Something" must be integer
*/
public function testShouldThrowTypeExceptionWhenCheckingAnInvalidInput()
{
$rule = new Type('integer');
$rule->check('Something');
}
public function providerForValidType()
{
return array(
array('array', array()),
array('bool', true),
array('boolean', false),
array('callable', function () {}),
array('double', 0.8),
array('float', 1.0),
array('int', 42),
array('integer', 13),
array('null', null),
array('object', new stdClass()),
array('resource', tmpfile()),
array('string', 'Something'),
);
}
public function providerForInvalidType()
{
return array(
array('int', '1'),
array('bool', '1'),
);
}
}