feature #11673 [Validator] Added date support to comparison constraints and Range (webmozart)
This PR was merged into the 2.6-dev branch.
Discussion
----------
[Validator] Added date support to comparison constraints and Range
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #3640, #7766, #9164, #9390, #8300
| License | MIT
| Doc PR | symfony/symfony-docs#4143
This commit adds frequently requested functionality to compare dates. Since the `DateTime` constructor is very flexible, you can do many fancy things now such as:
```php
/**
* Only accept requests that start in at least an hour.
* @Assert\GreaterThanOrEqual("+1 hours")
*/
private $date;
/**
* Same as before.
* @Assert\Range(min = "+1 hours")
*/
private $date;
/**
* Only accept dates in the current year.
* @Assert\Range(min = "first day of January", max = "first day of January next year")
*/
private $date;
/**
* Timezones are supported.
* @Assert\Range(min = "first day of January UTC", max = "first day of January next year UTC")
*/
private $date;
```
Commits
-------
60a5863
[Validator] Added date support to comparison constraints and Range
This commit is contained in:
commit
1d7684ac3d
@ -89,11 +89,22 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface
|
|||||||
*/
|
*/
|
||||||
protected function formatValue($value, $format = 0)
|
protected function formatValue($value, $format = 0)
|
||||||
{
|
{
|
||||||
if (($format & self::PRETTY_DATE) && $value instanceof \DateTime) {
|
$isDateTime = $value instanceof \DateTime || $value instanceof \DateTimeInterface;
|
||||||
|
|
||||||
|
if (($format & self::PRETTY_DATE) && $isDateTime) {
|
||||||
if (class_exists('IntlDateFormatter')) {
|
if (class_exists('IntlDateFormatter')) {
|
||||||
$locale = \Locale::getDefault();
|
$locale = \Locale::getDefault();
|
||||||
$formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT);
|
$formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT);
|
||||||
|
|
||||||
|
// neither the native nor the stub IntlDateFormatter support
|
||||||
|
// DateTimeImmutable as of yet
|
||||||
|
if (!$value instanceof \DateTime) {
|
||||||
|
$value = new \DateTime(
|
||||||
|
$value->format('Y-m-d H:i:s.u e'),
|
||||||
|
$value->getTimezone()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return $formatter->format($value);
|
return $formatter->format($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +35,28 @@ abstract class AbstractComparisonValidator extends ConstraintValidator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->compareValues($value, $constraint->value)) {
|
$comparedValue = $constraint->value;
|
||||||
|
|
||||||
|
// Convert strings to DateTimes if comparing another DateTime
|
||||||
|
// This allows to compare with any date/time value supported by
|
||||||
|
// the DateTime constructor:
|
||||||
|
// http://php.net/manual/en/datetime.formats.php
|
||||||
|
if (is_string($comparedValue)) {
|
||||||
|
if ($value instanceof \DatetimeImmutable) {
|
||||||
|
// If $value is immutable, convert the compared value to a
|
||||||
|
// DateTimeImmutable too
|
||||||
|
$comparedValue = new \DatetimeImmutable($comparedValue);
|
||||||
|
} elseif ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
|
||||||
|
// Otherwise use DateTime
|
||||||
|
$comparedValue = new \DateTime($comparedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->compareValues($value, $comparedValue)) {
|
||||||
$this->context->addViolation($constraint->message, array(
|
$this->context->addViolation($constraint->message, array(
|
||||||
'{{ value }}' => $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE),
|
'{{ value }}' => $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE),
|
||||||
'{{ compared_value }}' => $this->formatValue($constraint->value, self::OBJECT_TO_STRING | self::PRETTY_DATE),
|
'{{ compared_value }}' => $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE),
|
||||||
'{{ compared_value_type }}' => $this->formatTypeOf($constraint->value)
|
'{{ compared_value_type }}' => $this->formatTypeOf($comparedValue)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class RangeValidator extends ConstraintValidator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_numeric($value)) {
|
if (!is_numeric($value) && !$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
|
||||||
$this->context->addViolation($constraint->invalidMessage, array(
|
$this->context->addViolation($constraint->invalidMessage, array(
|
||||||
'{{ value }}' => $this->formatValue($value),
|
'{{ value }}' => $this->formatValue($value),
|
||||||
));
|
));
|
||||||
@ -41,19 +41,36 @@ class RangeValidator extends ConstraintValidator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $constraint->max && $value > $constraint->max) {
|
$min = $constraint->min;
|
||||||
|
$max = $constraint->max;
|
||||||
|
|
||||||
|
// Convert strings to DateTimes if comparing another DateTime
|
||||||
|
// This allows to compare with any date/time value supported by
|
||||||
|
// the DateTime constructor:
|
||||||
|
// http://php.net/manual/en/datetime.formats.php
|
||||||
|
if ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
|
||||||
|
if (is_string($min)) {
|
||||||
|
$min = new \DateTime($min);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($max)) {
|
||||||
|
$max = new \DateTime($max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $constraint->max && $value > $max) {
|
||||||
$this->context->addViolation($constraint->maxMessage, array(
|
$this->context->addViolation($constraint->maxMessage, array(
|
||||||
'{{ value }}' => $value,
|
'{{ value }}' => $value,
|
||||||
'{{ limit }}' => $constraint->max,
|
'{{ limit }}' => $this->formatValue($max, self::PRETTY_DATE),
|
||||||
));
|
));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $constraint->min && $value < $constraint->min) {
|
if (null !== $constraint->min && $value < $min) {
|
||||||
$this->context->addViolation($constraint->minMessage, array(
|
$this->context->addViolation($constraint->minMessage, array(
|
||||||
'{{ value }}' => $value,
|
'{{ value }}' => $value,
|
||||||
'{{ limit }}' => $constraint->min,
|
'{{ limit }}' => $this->formatValue($min, self::PRETTY_DATE),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,40 @@ class ComparisonTest_Class
|
|||||||
*/
|
*/
|
||||||
abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintValidatorTest
|
abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintValidatorTest
|
||||||
{
|
{
|
||||||
|
protected static function addPhp5Dot5Comparisons(array $comparisons)
|
||||||
|
{
|
||||||
|
if (version_compare(PHP_VERSION, '5.5.0-dev', '<')) {
|
||||||
|
return $comparisons;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $comparisons;
|
||||||
|
|
||||||
|
// Duplicate all tests involving DateTime objects to be tested with
|
||||||
|
// DateTimeImmutable objects as well
|
||||||
|
foreach ($comparisons as $comparison) {
|
||||||
|
$add = false;
|
||||||
|
|
||||||
|
foreach ($comparison as $i => $value) {
|
||||||
|
if ($value instanceof \DateTime) {
|
||||||
|
$comparison[$i] = new \DateTimeImmutable(
|
||||||
|
$value->format('Y-m-d H:i:s.u e'),
|
||||||
|
$value->getTimezone()
|
||||||
|
);
|
||||||
|
$add = true;
|
||||||
|
} elseif ('DateTime' === $value) {
|
||||||
|
$comparison[$i] = 'DateTimeImmutable';
|
||||||
|
$add = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($add) {
|
||||||
|
$result[] = $comparison;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
|
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
|
||||||
*/
|
*/
|
||||||
@ -45,7 +79,7 @@ abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintVal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideValidComparisons
|
* @dataProvider provideAllValidComparisons
|
||||||
* @param mixed $dirtyValue
|
* @param mixed $dirtyValue
|
||||||
* @param mixed $comparisonValue
|
* @param mixed $comparisonValue
|
||||||
*/
|
*/
|
||||||
@ -58,13 +92,29 @@ abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintVal
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function provideAllValidComparisons()
|
||||||
|
{
|
||||||
|
// The provider runs before setUp(), so we need to manually fix
|
||||||
|
// the default timezone
|
||||||
|
$this->setDefaultTimezone('UTC');
|
||||||
|
|
||||||
|
$comparisons = self::addPhp5Dot5Comparisons($this->provideValidComparisons());
|
||||||
|
|
||||||
|
$this->restoreDefaultTimezone();
|
||||||
|
|
||||||
|
return $comparisons;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
abstract public function provideValidComparisons();
|
abstract public function provideValidComparisons();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideInvalidComparisons
|
* @dataProvider provideAllInvalidComparisons
|
||||||
* @param mixed $dirtyValue
|
* @param mixed $dirtyValue
|
||||||
* @param mixed $dirtyValueAsString
|
* @param mixed $dirtyValueAsString
|
||||||
* @param mixed $comparedValue
|
* @param mixed $comparedValue
|
||||||
@ -75,7 +125,7 @@ abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintVal
|
|||||||
{
|
{
|
||||||
// Conversion of dates to string differs between ICU versions
|
// Conversion of dates to string differs between ICU versions
|
||||||
// Make sure we have the correct version loaded
|
// Make sure we have the correct version loaded
|
||||||
if ($dirtyValue instanceof \DateTime) {
|
if ($dirtyValue instanceof \DateTime || $dirtyValue instanceof \DateTimeInterface) {
|
||||||
IntlTestHelper::requireIntl($this);
|
IntlTestHelper::requireIntl($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +141,22 @@ abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintVal
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function provideAllInvalidComparisons()
|
||||||
|
{
|
||||||
|
// The provider runs before setUp(), so we need to manually fix
|
||||||
|
// the default timezone
|
||||||
|
$this->setDefaultTimezone('UTC');
|
||||||
|
|
||||||
|
$comparisons = self::addPhp5Dot5Comparisons($this->provideInvalidComparisons());
|
||||||
|
|
||||||
|
$this->restoreDefaultTimezone();
|
||||||
|
|
||||||
|
return $comparisons;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
@ -52,6 +52,8 @@ abstract class AbstractConstraintValidatorTest extends \PHPUnit_Framework_TestCa
|
|||||||
|
|
||||||
protected $constraint;
|
protected $constraint;
|
||||||
|
|
||||||
|
protected $defaultTimezone;
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
$this->group = 'MyGroup';
|
$this->group = 'MyGroup';
|
||||||
@ -74,6 +76,31 @@ abstract class AbstractConstraintValidatorTest extends \PHPUnit_Framework_TestCa
|
|||||||
$this->validator->initialize($this->context);
|
$this->validator->initialize($this->context);
|
||||||
|
|
||||||
\Locale::setDefault('en');
|
\Locale::setDefault('en');
|
||||||
|
|
||||||
|
$this->setDefaultTimezone('UTC');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
$this->restoreDefaultTimezone();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setDefaultTimezone($defaultTimezone)
|
||||||
|
{
|
||||||
|
// Make sure this method can not be called twice before calling
|
||||||
|
// also restoreDefaultTimezone()
|
||||||
|
if (null === $this->defaultTimezone) {
|
||||||
|
$this->defaultTimezone = ini_get('date.timezone');
|
||||||
|
ini_set('date.timezone', $defaultTimezone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function restoreDefaultTimezone()
|
||||||
|
{
|
||||||
|
if (null !== $this->defaultTimezone) {
|
||||||
|
ini_set('date.timezone', $this->defaultTimezone);
|
||||||
|
$this->defaultTimezone = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createContext()
|
protected function createContext()
|
||||||
|
@ -45,6 +45,8 @@ class EqualToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
array(3, '3'),
|
array(3, '3'),
|
||||||
array('a', 'a'),
|
array('a', 'a'),
|
||||||
array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
|
array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
|
||||||
|
array(new \DateTime('2000-01-01'), '2000-01-01'),
|
||||||
|
array(new \DateTime('2000-01-01 UTC'), '2000-01-01 UTC'),
|
||||||
array(new ComparisonTest_Class(5), new ComparisonTest_Class(5)),
|
array(new ComparisonTest_Class(5), new ComparisonTest_Class(5)),
|
||||||
array(null, 1),
|
array(null, 1),
|
||||||
);
|
);
|
||||||
@ -59,6 +61,8 @@ class EqualToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
array(1, '1', 2, '2', 'integer'),
|
array(1, '1', 2, '2', 'integer'),
|
||||||
array('22', '"22"', '333', '"333"', 'string'),
|
array('22', '"22"', '333', '"333"', 'string'),
|
||||||
array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2001-01-01 UTC'), 'Jan 1, 2001, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,10 @@ class GreaterThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCas
|
|||||||
array(1, 1),
|
array(1, 1),
|
||||||
array(new \DateTime('2010/01/01'), new \DateTime('2000/01/01')),
|
array(new \DateTime('2010/01/01'), new \DateTime('2000/01/01')),
|
||||||
array(new \DateTime('2000/01/01'), new \DateTime('2000/01/01')),
|
array(new \DateTime('2000/01/01'), new \DateTime('2000/01/01')),
|
||||||
|
array(new \DateTime('2010/01/01'), '2000/01/01'),
|
||||||
|
array(new \DateTime('2000/01/01'), '2000/01/01'),
|
||||||
|
array(new \DateTime('2010/01/01 UTC'), '2000/01/01 UTC'),
|
||||||
|
array(new \DateTime('2000/01/01 UTC'), '2000/01/01 UTC'),
|
||||||
array('a', 'a'),
|
array('a', 'a'),
|
||||||
array('z', 'a'),
|
array('z', 'a'),
|
||||||
array(null, 1),
|
array(null, 1),
|
||||||
@ -59,6 +63,8 @@ class GreaterThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCas
|
|||||||
return array(
|
return array(
|
||||||
array(1, '1', 2, '2', 'integer'),
|
array(1, '1', 2, '2', 'integer'),
|
||||||
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'),
|
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', '2005/01/01', 'Jan 1, 2005, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000/01/01 UTC'), 'Jan 1, 2000, 12:00 AM', '2005/01/01 UTC', 'Jan 1, 2005, 12:00 AM', 'DateTime'),
|
||||||
array('b', '"b"', 'c', '"c"', 'string')
|
array('b', '"b"', 'c', '"c"', 'string')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
return array(
|
return array(
|
||||||
array(2, 1),
|
array(2, 1),
|
||||||
array(new \DateTime('2005/01/01'), new \DateTime('2001/01/01')),
|
array(new \DateTime('2005/01/01'), new \DateTime('2001/01/01')),
|
||||||
|
array(new \DateTime('2005/01/01'), '2001/01/01'),
|
||||||
|
array(new \DateTime('2005/01/01 UTC'), '2001/01/01 UTC'),
|
||||||
array(new ComparisonTest_Class(5), new ComparisonTest_Class(4)),
|
array(new ComparisonTest_Class(5), new ComparisonTest_Class(4)),
|
||||||
array('333', '22'),
|
array('333', '22'),
|
||||||
array(null, 1),
|
array(null, 1),
|
||||||
@ -59,6 +61,10 @@ class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
array(2, '2', 2, '2', 'integer'),
|
array(2, '2', 2, '2', 'integer'),
|
||||||
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'),
|
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'),
|
||||||
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', '2005/01/01', 'Jan 1, 2005, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', '2000/01/01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000/01/01 UTC'), 'Jan 1, 2000, 12:00 AM', '2005/01/01 UTC', 'Jan 1, 2005, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000/01/01 UTC'), 'Jan 1, 2000, 12:00 AM', '2000/01/01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||||
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||||
array('22', '"22"', '333', '"333"', 'string'),
|
array('22', '"22"', '333', '"333"', 'string'),
|
||||||
|
@ -35,6 +35,19 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
return new IdenticalTo($options);
|
return new IdenticalTo($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideAllValidComparisons()
|
||||||
|
{
|
||||||
|
$this->setDefaultTimezone('UTC');
|
||||||
|
|
||||||
|
// Don't call addPhp5Dot5Comparisons() automatically, as it does
|
||||||
|
// not take care of identical objects
|
||||||
|
$comparisons = $this->provideValidComparisons();
|
||||||
|
|
||||||
|
$this->restoreDefaultTimezone();
|
||||||
|
|
||||||
|
return $comparisons;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -43,13 +56,20 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
$date = new \DateTime('2000-01-01');
|
$date = new \DateTime('2000-01-01');
|
||||||
$object = new ComparisonTest_Class(2);
|
$object = new ComparisonTest_Class(2);
|
||||||
|
|
||||||
return array(
|
$comparisons = array(
|
||||||
array(3, 3),
|
array(3, 3),
|
||||||
array('a', 'a'),
|
array('a', 'a'),
|
||||||
array($date, $date),
|
array($date, $date),
|
||||||
array($object, $object),
|
array($object, $object),
|
||||||
array(null, 1),
|
array(null, 1),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '>=', '5.5')) {
|
||||||
|
$immutableDate = new \DateTimeImmutable('2000-01-01');
|
||||||
|
$comparisons[] = array($immutableDate, $immutableDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $comparisons;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,6 +45,10 @@ class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
array(1, 1),
|
array(1, 1),
|
||||||
array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
|
array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
|
||||||
array(new \DateTime('2000-01-01'), new \DateTime('2020-01-01')),
|
array(new \DateTime('2000-01-01'), new \DateTime('2020-01-01')),
|
||||||
|
array(new \DateTime('2000-01-01'), '2000-01-01'),
|
||||||
|
array(new \DateTime('2000-01-01'), '2020-01-01'),
|
||||||
|
array(new \DateTime('2000-01-01 UTC'), '2000-01-01 UTC'),
|
||||||
|
array(new \DateTime('2000-01-01 UTC'), '2020-01-01 UTC'),
|
||||||
array(new ComparisonTest_Class(4), new ComparisonTest_Class(5)),
|
array(new ComparisonTest_Class(4), new ComparisonTest_Class(5)),
|
||||||
array(new ComparisonTest_Class(5), new ComparisonTest_Class(5)),
|
array(new ComparisonTest_Class(5), new ComparisonTest_Class(5)),
|
||||||
array('a', 'a'),
|
array('a', 'a'),
|
||||||
@ -61,6 +65,8 @@ class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
return array(
|
return array(
|
||||||
array(2, '2', 1, '1', 'integer'),
|
array(2, '2', 1, '1', 'integer'),
|
||||||
array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2010-01-01 UTC'), 'Jan 1, 2010, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(4), '4', __NAMESPACE__.'\ComparisonTest_Class'),
|
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(4), '4', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||||
array('c', '"c"', 'b', '"b"', 'string')
|
array('c', '"c"', 'b', '"b"', 'string')
|
||||||
);
|
);
|
||||||
|
@ -43,6 +43,8 @@ class LessThanValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
return array(
|
return array(
|
||||||
array(1, 2),
|
array(1, 2),
|
||||||
array(new \DateTime('2000-01-01'), new \DateTime('2010-01-01')),
|
array(new \DateTime('2000-01-01'), new \DateTime('2010-01-01')),
|
||||||
|
array(new \DateTime('2000-01-01'), '2010-01-01'),
|
||||||
|
array(new \DateTime('2000-01-01 UTC'), '2010-01-01 UTC'),
|
||||||
array(new ComparisonTest_Class(4), new ComparisonTest_Class(5)),
|
array(new ComparisonTest_Class(4), new ComparisonTest_Class(5)),
|
||||||
array('22', '333'),
|
array('22', '333'),
|
||||||
array(null, 1),
|
array(null, 1),
|
||||||
@ -59,6 +61,10 @@ class LessThanValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
array(2, '2', 2, '2', 'integer'),
|
array(2, '2', 2, '2', 'integer'),
|
||||||
array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2010-01-01 UTC'), 'Jan 1, 2010, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000-01-01 UTC'), 'Jan 1, 2000, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||||
array(new ComparisonTest_Class(6), '6', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
array(new ComparisonTest_Class(6), '6', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||||
array('333', '"333"', '22', '"22"', 'string'),
|
array('333', '"333"', '22', '"22"', 'string'),
|
||||||
|
@ -44,6 +44,8 @@ class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
array(1, 2),
|
array(1, 2),
|
||||||
array('22', '333'),
|
array('22', '333'),
|
||||||
array(new \DateTime('2001-01-01'), new \DateTime('2000-01-01')),
|
array(new \DateTime('2001-01-01'), new \DateTime('2000-01-01')),
|
||||||
|
array(new \DateTime('2001-01-01'), '2000-01-01'),
|
||||||
|
array(new \DateTime('2001-01-01 UTC'), '2000-01-01 UTC'),
|
||||||
array(new ComparisonTest_Class(6), new ComparisonTest_Class(5)),
|
array(new ComparisonTest_Class(6), new ComparisonTest_Class(5)),
|
||||||
array(null, 1),
|
array(null, 1),
|
||||||
);
|
);
|
||||||
@ -59,6 +61,8 @@ class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
array('2', '"2"', 2, '2', 'integer'),
|
array('2', '"2"', 2, '2', 'integer'),
|
||||||
array('a', '"a"', 'a', '"a"', 'string'),
|
array('a', '"a"', 'a', '"a"', 'string'),
|
||||||
array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
|
array(new \DateTime('2000-01-01 UTC'), 'Jan 1, 2000, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,27 @@ class NotIdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
array('22', '333'),
|
array('22', '333'),
|
||||||
array(new \DateTime('2001-01-01'), new \DateTime('2000-01-01')),
|
array(new \DateTime('2001-01-01'), new \DateTime('2000-01-01')),
|
||||||
array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
|
array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
|
||||||
|
array(new \DateTime('2001-01-01'), '2000-01-01'),
|
||||||
|
array(new \DateTime('2000-01-01'), '2000-01-01'),
|
||||||
|
array(new \DateTime('2001-01-01'), '2000-01-01'),
|
||||||
|
array(new \DateTime('2000-01-01 UTC'), '2000-01-01 UTC'),
|
||||||
array(null, 1),
|
array(null, 1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideAllInvalidComparisons()
|
||||||
|
{
|
||||||
|
$this->setDefaultTimezone('UTC');
|
||||||
|
|
||||||
|
// Don't call addPhp5Dot5Comparisons() automatically, as it does
|
||||||
|
// not take care of identical objects
|
||||||
|
$comparisons = $this->provideInvalidComparisons();
|
||||||
|
|
||||||
|
$this->restoreDefaultTimezone();
|
||||||
|
|
||||||
|
return $comparisons;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -58,11 +75,18 @@ class NotIdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||||||
$date = new \DateTime('2000-01-01');
|
$date = new \DateTime('2000-01-01');
|
||||||
$object = new ComparisonTest_Class(2);
|
$object = new ComparisonTest_Class(2);
|
||||||
|
|
||||||
return array(
|
$comparisons = array(
|
||||||
array(3, '3', 3, '3', 'integer'),
|
array(3, '3', 3, '3', 'integer'),
|
||||||
array('a', '"a"', 'a', '"a"', 'string'),
|
array('a', '"a"', 'a', '"a"', 'string'),
|
||||||
array($date, 'Jan 1, 2000, 12:00 AM', $date, 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
array($date, 'Jan 1, 2000, 12:00 AM', $date, 'Jan 1, 2000, 12:00 AM', 'DateTime'),
|
||||||
array($object, '2', $object, '2', __NAMESPACE__.'\ComparisonTest_Class'),
|
array($object, '2', $object, '2', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '>=', '5.5')) {
|
||||||
|
$immutableDate = new \DateTimeImmutable('2000-01-01');
|
||||||
|
$comparisons[] = array($immutableDate, 'Jan 1, 2000, 12:00 AM', $immutableDate, 'Jan 1, 2000, 12:00 AM', 'DateTime');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $comparisons;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Validator\Tests\Constraints;
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use Symfony\Component\Intl\Util\IntlTestHelper;
|
||||||
use Symfony\Component\Validator\Constraints\Range;
|
use Symfony\Component\Validator\Constraints\Range;
|
||||||
use Symfony\Component\Validator\Constraints\RangeValidator;
|
use Symfony\Component\Validator\Constraints\RangeValidator;
|
||||||
use Symfony\Component\Validator\Validation;
|
use Symfony\Component\Validator\Validation;
|
||||||
@ -177,6 +178,196 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTenthToTwentiethMarch2014()
|
||||||
|
{
|
||||||
|
// The provider runs before setUp(), so we need to manually fix
|
||||||
|
// the default timezone
|
||||||
|
$this->setDefaultTimezone('UTC');
|
||||||
|
|
||||||
|
$tests = array(
|
||||||
|
array(new \DateTime('March 10, 2014')),
|
||||||
|
array(new \DateTime('March 15, 2014')),
|
||||||
|
array(new \DateTime('March 20, 2014')),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
|
||||||
|
$tests[] = array(new \DateTimeImmutable('March 10, 2014'));
|
||||||
|
$tests[] = array(new \DateTimeImmutable('March 15, 2014'));
|
||||||
|
$tests[] = array(new \DateTimeImmutable('March 20, 2014'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->restoreDefaultTimezone();
|
||||||
|
|
||||||
|
return $tests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSoonerThanTenthMarch2014()
|
||||||
|
{
|
||||||
|
// The provider runs before setUp(), so we need to manually fix
|
||||||
|
// the default timezone
|
||||||
|
$this->setDefaultTimezone('UTC');
|
||||||
|
|
||||||
|
$tests = array(
|
||||||
|
array(new \DateTime('March 20, 2013')),
|
||||||
|
array(new \DateTime('March 9, 2014')),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
|
||||||
|
$tests[] = array(new \DateTimeImmutable('March 20, 2013'));
|
||||||
|
$tests[] = array(new \DateTimeImmutable('March 9, 2014'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->restoreDefaultTimezone();
|
||||||
|
|
||||||
|
return $tests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLaterThanTwentiethMarch2014()
|
||||||
|
{
|
||||||
|
// The provider runs before setUp(), so we need to manually fix
|
||||||
|
// the default timezone
|
||||||
|
$this->setDefaultTimezone('UTC');
|
||||||
|
|
||||||
|
$tests = array(
|
||||||
|
array(new \DateTime('March 21, 2014')),
|
||||||
|
array(new \DateTime('March 9, 2015')),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
|
||||||
|
$tests[] = array(new \DateTimeImmutable('March 21, 2014'));
|
||||||
|
$tests[] = array(new \DateTimeImmutable('March 9, 2015'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->restoreDefaultTimezone();
|
||||||
|
|
||||||
|
return $tests;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getTenthToTwentiethMarch2014
|
||||||
|
*/
|
||||||
|
public function testValidDatesMin($value)
|
||||||
|
{
|
||||||
|
$constraint = new Range(array('min' => 'March 10, 2014'));
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getTenthToTwentiethMarch2014
|
||||||
|
*/
|
||||||
|
public function testValidDatesMax($value)
|
||||||
|
{
|
||||||
|
$constraint = new Range(array('max' => 'March 20, 2014'));
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getTenthToTwentiethMarch2014
|
||||||
|
*/
|
||||||
|
public function testValidDatesMinMax($value)
|
||||||
|
{
|
||||||
|
$constraint = new Range(array('min' => 'March 10, 2014', 'max' => 'March 20, 2014'));
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getSoonerThanTenthMarch2014
|
||||||
|
*/
|
||||||
|
public function testInvalidDatesMin($value)
|
||||||
|
{
|
||||||
|
// Conversion of dates to string differs between ICU versions
|
||||||
|
// Make sure we have the correct version loaded
|
||||||
|
IntlTestHelper::requireIntl($this);
|
||||||
|
|
||||||
|
$constraint = new Range(array(
|
||||||
|
'min' => 'March 10, 2014',
|
||||||
|
'minMessage' => 'myMessage',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertViolation('myMessage', array(
|
||||||
|
'{{ value }}' => $value,
|
||||||
|
'{{ limit }}' => 'Mar 10, 2014, 12:00 AM',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getLaterThanTwentiethMarch2014
|
||||||
|
*/
|
||||||
|
public function testInvalidDatesMax($value)
|
||||||
|
{
|
||||||
|
// Conversion of dates to string differs between ICU versions
|
||||||
|
// Make sure we have the correct version loaded
|
||||||
|
IntlTestHelper::requireIntl($this);
|
||||||
|
|
||||||
|
$constraint = new Range(array(
|
||||||
|
'max' => 'March 20, 2014',
|
||||||
|
'maxMessage' => 'myMessage',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertViolation('myMessage', array(
|
||||||
|
'{{ value }}' => $value,
|
||||||
|
'{{ limit }}' => 'Mar 20, 2014, 12:00 AM',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getLaterThanTwentiethMarch2014
|
||||||
|
*/
|
||||||
|
public function testInvalidDatesCombinedMax($value)
|
||||||
|
{
|
||||||
|
// Conversion of dates to string differs between ICU versions
|
||||||
|
// Make sure we have the correct version loaded
|
||||||
|
IntlTestHelper::requireIntl($this);
|
||||||
|
|
||||||
|
$constraint = new Range(array(
|
||||||
|
'min' => 'March 10, 2014',
|
||||||
|
'max' => 'March 20, 2014',
|
||||||
|
'minMessage' => 'myMinMessage',
|
||||||
|
'maxMessage' => 'myMaxMessage',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertViolation('myMaxMessage', array(
|
||||||
|
'{{ value }}' => $value,
|
||||||
|
'{{ limit }}' => 'Mar 20, 2014, 12:00 AM',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getSoonerThanTenthMarch2014
|
||||||
|
*/
|
||||||
|
public function testInvalidDatesCombinedMin($value)
|
||||||
|
{
|
||||||
|
// Conversion of dates to string differs between ICU versions
|
||||||
|
// Make sure we have the correct version loaded
|
||||||
|
IntlTestHelper::requireIntl($this);
|
||||||
|
|
||||||
|
$constraint = new Range(array(
|
||||||
|
'min' => 'March 10, 2014',
|
||||||
|
'max' => 'March 20, 2014',
|
||||||
|
'minMessage' => 'myMinMessage',
|
||||||
|
'maxMessage' => 'myMaxMessage',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertViolation('myMinMessage', array(
|
||||||
|
'{{ value }}' => $value,
|
||||||
|
'{{ limit }}' => 'Mar 10, 2014, 12:00 AM',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
public function getInvalidValues()
|
public function getInvalidValues()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
Reference in New Issue
Block a user