diff --git a/ConstraintValidator.php b/ConstraintValidator.php index 58c0902e1..772bf5d55 100644 --- a/ConstraintValidator.php +++ b/ConstraintValidator.php @@ -89,11 +89,22 @@ protected function formatTypeOf($value) */ 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')) { $locale = \Locale::getDefault(); $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); } diff --git a/Constraints/AbstractComparisonValidator.php b/Constraints/AbstractComparisonValidator.php index a395f9764..811c7a139 100644 --- a/Constraints/AbstractComparisonValidator.php +++ b/Constraints/AbstractComparisonValidator.php @@ -35,11 +35,28 @@ public function validate($value, Constraint $constraint) 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( '{{ 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_type }}' => $this->formatTypeOf($constraint->value) + '{{ compared_value }}' => $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE), + '{{ compared_value_type }}' => $this->formatTypeOf($comparedValue) )); } } diff --git a/Constraints/RangeValidator.php b/Constraints/RangeValidator.php index c7bf7a93b..1cb685fe0 100644 --- a/Constraints/RangeValidator.php +++ b/Constraints/RangeValidator.php @@ -33,7 +33,7 @@ public function validate($value, Constraint $constraint) return; } - if (!is_numeric($value)) { + if (!is_numeric($value) && !$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { $this->context->addViolation($constraint->invalidMessage, array( '{{ value }}' => $this->formatValue($value), )); @@ -41,19 +41,36 @@ public function validate($value, Constraint $constraint) 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( '{{ value }}' => $value, - '{{ limit }}' => $constraint->max, + '{{ limit }}' => $this->formatValue($max, self::PRETTY_DATE), )); return; } - if (null !== $constraint->min && $value < $constraint->min) { + if (null !== $constraint->min && $value < $min) { $this->context->addViolation($constraint->minMessage, array( '{{ value }}' => $value, - '{{ limit }}' => $constraint->min, + '{{ limit }}' => $this->formatValue($min, self::PRETTY_DATE), )); } } diff --git a/Tests/Constraints/AbstractComparisonValidatorTestCase.php b/Tests/Constraints/AbstractComparisonValidatorTestCase.php index a56f73455..77d1ff61c 100644 --- a/Tests/Constraints/AbstractComparisonValidatorTestCase.php +++ b/Tests/Constraints/AbstractComparisonValidatorTestCase.php @@ -34,6 +34,40 @@ public function __toString() */ 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 */ @@ -45,7 +79,7 @@ public function testThrowsConstraintExceptionIfNoValueOrProperty() } /** - * @dataProvider provideValidComparisons + * @dataProvider provideAllValidComparisons * @param mixed $dirtyValue * @param mixed $comparisonValue */ @@ -58,13 +92,29 @@ public function testValidComparisonToValue($dirtyValue, $comparisonValue) $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 */ abstract public function provideValidComparisons(); /** - * @dataProvider provideInvalidComparisons + * @dataProvider provideAllInvalidComparisons * @param mixed $dirtyValue * @param mixed $dirtyValueAsString * @param mixed $comparedValue @@ -75,7 +125,7 @@ public function testInvalidComparisonToValue($dirtyValue, $dirtyValueAsString, $ { // Conversion of dates to string differs between ICU versions // Make sure we have the correct version loaded - if ($dirtyValue instanceof \DateTime) { + if ($dirtyValue instanceof \DateTime || $dirtyValue instanceof \DateTimeInterface) { IntlTestHelper::requireIntl($this); } @@ -91,6 +141,22 @@ public function testInvalidComparisonToValue($dirtyValue, $dirtyValueAsString, $ )); } + /** + * @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 */ diff --git a/Tests/Constraints/AbstractConstraintValidatorTest.php b/Tests/Constraints/AbstractConstraintValidatorTest.php index ef29fe34a..985b6a73f 100644 --- a/Tests/Constraints/AbstractConstraintValidatorTest.php +++ b/Tests/Constraints/AbstractConstraintValidatorTest.php @@ -52,6 +52,8 @@ abstract class AbstractConstraintValidatorTest extends \PHPUnit_Framework_TestCa protected $constraint; + protected $defaultTimezone; + protected function setUp() { $this->group = 'MyGroup'; @@ -74,6 +76,31 @@ protected function setUp() $this->validator->initialize($this->context); \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() diff --git a/Tests/Constraints/EqualToValidatorTest.php b/Tests/Constraints/EqualToValidatorTest.php index 0fd4a044c..c20db1550 100644 --- a/Tests/Constraints/EqualToValidatorTest.php +++ b/Tests/Constraints/EqualToValidatorTest.php @@ -45,6 +45,8 @@ public function provideValidComparisons() array(3, '3'), array('a', 'a'), 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(null, 1), ); @@ -59,6 +61,8 @@ public function provideInvalidComparisons() array(1, '1', 2, '2', 'integer'), 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', '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'), ); } diff --git a/Tests/Constraints/GreaterThanOrEqualValidatorTest.php b/Tests/Constraints/GreaterThanOrEqualValidatorTest.php index ed1f47b1f..5cb807554 100644 --- a/Tests/Constraints/GreaterThanOrEqualValidatorTest.php +++ b/Tests/Constraints/GreaterThanOrEqualValidatorTest.php @@ -45,6 +45,10 @@ public function provideValidComparisons() array(1, 1), 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('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('z', 'a'), array(null, 1), @@ -59,6 +63,8 @@ public function provideInvalidComparisons() return array( 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', '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') ); } diff --git a/Tests/Constraints/GreaterThanValidatorTest.php b/Tests/Constraints/GreaterThanValidatorTest.php index e2f0fd38f..01e478c3f 100644 --- a/Tests/Constraints/GreaterThanValidatorTest.php +++ b/Tests/Constraints/GreaterThanValidatorTest.php @@ -43,6 +43,8 @@ public function provideValidComparisons() return array( array(2, 1), 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('333', '22'), array(null, 1), @@ -59,6 +61,10 @@ public function provideInvalidComparisons() 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('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(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), array('22', '"22"', '333', '"333"', 'string'), diff --git a/Tests/Constraints/IdenticalToValidatorTest.php b/Tests/Constraints/IdenticalToValidatorTest.php index 125a28443..4b71062f0 100644 --- a/Tests/Constraints/IdenticalToValidatorTest.php +++ b/Tests/Constraints/IdenticalToValidatorTest.php @@ -35,6 +35,19 @@ protected function createConstraint(array $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} */ @@ -43,13 +56,20 @@ public function provideValidComparisons() $date = new \DateTime('2000-01-01'); $object = new ComparisonTest_Class(2); - return array( + $comparisons = array( array(3, 3), array('a', 'a'), array($date, $date), array($object, $object), array(null, 1), ); + + if (version_compare(PHP_VERSION, '>=', '5.5')) { + $immutableDate = new \DateTimeImmutable('2000-01-01'); + $comparisons[] = array($immutableDate, $immutableDate); + } + + return $comparisons; } /** diff --git a/Tests/Constraints/LessThanOrEqualValidatorTest.php b/Tests/Constraints/LessThanOrEqualValidatorTest.php index 6a5f9ef1f..ee3e31731 100644 --- a/Tests/Constraints/LessThanOrEqualValidatorTest.php +++ b/Tests/Constraints/LessThanOrEqualValidatorTest.php @@ -45,6 +45,10 @@ public function provideValidComparisons() array(1, 1), 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'), '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(5), new ComparisonTest_Class(5)), array('a', 'a'), @@ -61,6 +65,8 @@ public function provideInvalidComparisons() return array( 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', '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('c', '"c"', 'b', '"b"', 'string') ); diff --git a/Tests/Constraints/LessThanValidatorTest.php b/Tests/Constraints/LessThanValidatorTest.php index eb534e58b..d555870c1 100644 --- a/Tests/Constraints/LessThanValidatorTest.php +++ b/Tests/Constraints/LessThanValidatorTest.php @@ -43,6 +43,8 @@ public function provideValidComparisons() return array( array(1, 2), 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('22', '333'), array(null, 1), @@ -59,6 +61,10 @@ public function provideInvalidComparisons() 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('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(6), '6', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), array('333', '"333"', '22', '"22"', 'string'), diff --git a/Tests/Constraints/NotEqualToValidatorTest.php b/Tests/Constraints/NotEqualToValidatorTest.php index 836d01848..bc2c348ef 100644 --- a/Tests/Constraints/NotEqualToValidatorTest.php +++ b/Tests/Constraints/NotEqualToValidatorTest.php @@ -44,6 +44,8 @@ public function provideValidComparisons() array(1, 2), array('22', '333'), 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(null, 1), ); @@ -59,6 +61,8 @@ public function provideInvalidComparisons() array('2', '"2"', 2, '2', 'integer'), 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', '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'), ); } diff --git a/Tests/Constraints/NotIdenticalToValidatorTest.php b/Tests/Constraints/NotIdenticalToValidatorTest.php index de676d437..1fbd80663 100644 --- a/Tests/Constraints/NotIdenticalToValidatorTest.php +++ b/Tests/Constraints/NotIdenticalToValidatorTest.php @@ -46,10 +46,27 @@ public function provideValidComparisons() array('22', '333'), 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('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), ); } + 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} */ @@ -58,11 +75,18 @@ public function provideInvalidComparisons() $date = new \DateTime('2000-01-01'); $object = new ComparisonTest_Class(2); - return array( + $comparisons = array( array(3, '3', 3, '3', 'integer'), array('a', '"a"', 'a', '"a"', 'string'), array($date, 'Jan 1, 2000, 12:00 AM', $date, 'Jan 1, 2000, 12:00 AM', 'DateTime'), 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; } } diff --git a/Tests/Constraints/RangeValidatorTest.php b/Tests/Constraints/RangeValidatorTest.php index 71477ad4f..807d05aa3 100644 --- a/Tests/Constraints/RangeValidatorTest.php +++ b/Tests/Constraints/RangeValidatorTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Validator\Tests\Constraints; +use Symfony\Component\Intl\Util\IntlTestHelper; use Symfony\Component\Validator\Constraints\Range; use Symfony\Component\Validator\Constraints\RangeValidator; use Symfony\Component\Validator\Validation; @@ -177,6 +178,196 @@ public function testInvalidValuesCombinedMin($value) )); } + 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() { return array(