-
Notifications
You must be signed in to change notification settings - Fork 772
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #305 from henriquemoody/age
Create "Age" rule
- Loading branch information
Showing
8 changed files
with
289 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Age | ||
|
||
- `v::age(int $minAge)` | ||
- `v::age(int $minAge, int $maxAge)` | ||
- `v::age(null, int $maxAge)` | ||
|
||
Validates ranges of years. | ||
|
||
The validated values can be any date value; internally they will be transformed | ||
into [DateTime](http://php.net/manual/en/class.datetime.php) objects according | ||
to the defined locale settings. | ||
|
||
The examples below validate if the given dates are lower or equal to 18 years ago: | ||
```php | ||
v::age(18)->validate('17 years ago'); //false | ||
v::age(18)->validate('18 years ago'); //true | ||
v::age(18)->validate('19 years ago'); //true | ||
v::age(18)->validate('1970-01-01'); //true | ||
v::age(18)->validate('today'); //false | ||
``` | ||
|
||
The examples below validate if the given dates are between 10 and 50 years ago: | ||
```php | ||
v::age(10, 50)->validate('9 years ago'); //false | ||
v::age(10, 50)->validate('10 years ago'); //true | ||
v::age(10, 50)->validate('30 years ago'); //true | ||
v::age(10, 50)->validate('50 years ago'); //true | ||
v::age(10, 50)->validate('51 years ago'); //false | ||
``` | ||
|
||
The examples below validate if the given dates are greater than or equal to 70 years ago: | ||
```php | ||
v::age(null, 70)->validate('today'); //true | ||
v::age(null, 70)->validate('70 years ago'); //true | ||
v::age(null, 70)->validate('71 years ago'); //false | ||
``` | ||
|
||
Message template for this validator includes `{{minAge}}` and `{{maxAge}}`. | ||
|
||
See also: | ||
|
||
* [Between](Between.md) | ||
* [Date](Date.md) | ||
* [Max](Max.md) | ||
* [Min](Min.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
namespace Respect\Validation\Exceptions; | ||
|
||
class AgeException extends AbstractNestedException | ||
{ | ||
const BOTH = 0; | ||
const LOWER = 1; | ||
const GREATER = 2; | ||
|
||
public static $defaultTemplates = array( | ||
self::MODE_DEFAULT => array( | ||
self::BOTH => '{{name}} must be between {{minAge}} and {{maxAge}} years ago', | ||
self::LOWER => '{{name}} must be lower than {{minAge}} years ago', | ||
self::GREATER => '{{name}} must be greater than {{maxAge}} years ago', | ||
), | ||
self::MODE_NEGATIVE => array( | ||
self::BOTH => '{{name}} must not be between {{minAge}} and {{maxAge}} years ago', | ||
self::LOWER => '{{name}} must not be lower than {{minAge}} years ago', | ||
self::GREATER => '{{name}} must not be greater than {{maxAge}} years ago', | ||
), | ||
); | ||
|
||
public function configure($name, array $params = array()) | ||
{ | ||
$params['minAge'] = static::stringify($params['minAge']); | ||
$params['maxAge'] = static::stringify($params['maxAge']); | ||
|
||
return parent::configure($name, $params); | ||
} | ||
|
||
public function chooseTemplate() | ||
{ | ||
if (!$this->getParam('minAge')) { | ||
return static::GREATER; | ||
} | ||
|
||
if (!$this->getParam('maxAge')) { | ||
return static::LOWER; | ||
} | ||
|
||
return static::BOTH; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?php | ||
namespace Respect\Validation\Rules; | ||
|
||
use DateTime; | ||
use Respect\Validation\Exceptions\ComponentException; | ||
|
||
class Age extends AllOf | ||
{ | ||
public $minAge; | ||
public $maxAge; | ||
|
||
public function __construct($minAge = null, $maxAge = null) | ||
{ | ||
if (null === $minAge && null === $maxAge) { | ||
throw new ComponentException('An age interval must be provided'); | ||
} | ||
|
||
if (null !== $minAge && null !== $maxAge && $maxAge <= $minAge) { | ||
throw new ComponentException(sprintf('%d cannot be greater than or equals to %d', $minAge, $maxAge)); | ||
} | ||
|
||
$this->setMinAge($minAge); | ||
$this->setMaxAge($maxAge); | ||
} | ||
|
||
private function createDateTimeFromAge($age) | ||
{ | ||
$interval = sprintf('-%d years', $age); | ||
|
||
return new DateTime($interval); | ||
} | ||
|
||
private function setMaxAge($maxAge) | ||
{ | ||
$this->maxAge = $maxAge; | ||
|
||
if (null === $maxAge) { | ||
return; | ||
} | ||
|
||
$minDate = $this->createDateTimeFromAge($maxAge); | ||
$minDate->setTime(0, 0, 0); | ||
|
||
$minRule = new Min($minDate, true); | ||
|
||
$this->addRule($minRule); | ||
} | ||
|
||
private function setMinAge($minAge) | ||
{ | ||
$this->minAge = $minAge; | ||
|
||
if (null === $minAge) { | ||
return; | ||
} | ||
|
||
$maxDate = $this->createDateTimeFromAge($minAge); | ||
$maxDate->setTime(23, 59, 59); | ||
|
||
$maxRule = new Max($maxDate, true); | ||
|
||
$this->addRule($maxRule); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
<?php | ||
namespace Respect\Validation\Rules; | ||
|
||
use DateTime; | ||
|
||
/** | ||
* @covers Respect\Validation\Rules\Age | ||
* @covers Respect\Validation\Exceptions\AgeException | ||
*/ | ||
class AgeTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @expectedException Respect\Validation\Exceptions\ComponentException | ||
* @expectedExceptionMessage An age interval must be provided | ||
*/ | ||
public function testShouldThrowsExceptionWhenThereIsNoArgumentsOnConstructor() | ||
{ | ||
new Age(); | ||
} | ||
/** | ||
* @expectedException Respect\Validation\Exceptions\ComponentException | ||
* @expectedExceptionMessage 20 cannot be greater than or equals to 10 | ||
*/ | ||
public function testShouldThrowsExceptionWhenMinimumAgeIsLessThenMaximumAge() | ||
{ | ||
new Age(20, 10); | ||
} | ||
|
||
/** | ||
* @expectedException Respect\Validation\Exceptions\ComponentException | ||
* @expectedExceptionMessage 20 cannot be greater than or equals to 20 | ||
*/ | ||
public function testShouldThrowsExceptionWhenMinimumAgeIsEqualsToMaximumAge() | ||
{ | ||
new Age(20, 20); | ||
} | ||
|
||
public function providerForValidAge() | ||
{ | ||
return array( | ||
array(18, null, date('Y-m-d', strtotime('-18 years'))), | ||
array(18, null, date('Y-m-d', strtotime('-19 years'))), | ||
array(18, null, new DateTime('-18 years')), | ||
array(18, null, new DateTime('-19 years')), | ||
|
||
array(18, 50, date('Y-m-d', strtotime('-18 years'))), | ||
array(18, 50, date('Y-m-d', strtotime('-50 years'))), | ||
array(18, 50, new DateTime('-18 years')), | ||
array(18, 50, new DateTime('-50 years')), | ||
|
||
array(null, 50, date('Y-m-d', strtotime('-49 years'))), | ||
array(null, 50, date('Y-m-d', strtotime('-50 years'))), | ||
array(null, 50, new DateTime('-49 years')), | ||
array(null, 50, new DateTime('-50 years')), | ||
); | ||
} | ||
|
||
/** | ||
* @dataProvider providerForValidAge | ||
*/ | ||
public function testShouldValidateValidAge($minAge, $maxAge, $input) | ||
{ | ||
$rule = new Age($minAge, $maxAge); | ||
|
||
$this->assertTrue($rule->validate($input)); | ||
} | ||
|
||
public function providerForInvalidAge() | ||
{ | ||
return array( | ||
array(18, null, date('Y-m-d', strtotime('-17 years'))), | ||
array(18, null, new DateTime('-17 years')), | ||
|
||
array(18, 50, date('Y-m-d', strtotime('-17 years'))), | ||
array(18, 50, date('Y-m-d', strtotime('-51 years'))), | ||
array(18, 50, new DateTime('-17 years')), | ||
array(18, 50, new DateTime('-51 years')), | ||
|
||
array(null, 50, date('Y-m-d', strtotime('-51 years'))), | ||
array(null, 50, new DateTime('-51 years')), | ||
); | ||
} | ||
|
||
/** | ||
* @dataProvider providerForInvalidAge | ||
*/ | ||
public function testShouldValidateInvalidAge($minAge, $maxAge, $input) | ||
{ | ||
$rule = new Age($minAge, $maxAge); | ||
|
||
$this->assertFalse($rule->validate($input)); | ||
} | ||
|
||
/** | ||
* @depends testShouldValidateInvalidAge | ||
* | ||
* @expectedException Respect\Validation\Exceptions\AgeException | ||
* @expectedExceptionMessage "today" must be lower than 18 years ago | ||
*/ | ||
public function testShouldThrowsExceptionWhenMinimumAgeFails() | ||
{ | ||
$rule = new Age(18); | ||
$rule->assert('today'); | ||
} | ||
|
||
/** | ||
* @depends testShouldValidateInvalidAge | ||
* | ||
* @expectedException Respect\Validation\Exceptions\AgeException | ||
* @expectedExceptionMessage "51 years ago" must be greater than 50 years ago | ||
*/ | ||
public function testShouldThrowsExceptionWhenMaximunAgeFails() | ||
{ | ||
$rule = new Age(null, 50); | ||
$rule->assert('51 years ago'); | ||
} | ||
|
||
/** | ||
* @depends testShouldValidateInvalidAge | ||
* | ||
* @expectedException Respect\Validation\Exceptions\AgeException | ||
* @expectedExceptionMessage "today" must be between 18 and 50 years ago | ||
*/ | ||
public function testShouldThrowsExceptionWhenMinimunAndMaximunAgeFails() | ||
{ | ||
$rule = new Age(18, 50); | ||
$rule->assert('today'); | ||
} | ||
} |