Merge branch '2.4' into 2.5
* 2.4:
[Validator] Backported constraint validator tests from 2.5
[Validator] Backported constraint validator tests from 2.5
Fix toolbar vertical alignment.
[HttpFoundation] MongoDbSessionHandler supports auto expiry via configurable expiry_field
[FrameworkBundle] add missing attribute to XSD
Allow basic auth in url. Improve regex. Add tests.
fix typos and syntax in Profiler controller method comments
remove volatile tests
[Console] fixed style creation when providing an unknown tag option
[Validator] Convert objects to string in comparison validators. Reapplies 6cf5e0812e
[HttpFoundation] Update QUERY_STRING when overrideGlobals
Conflicts:
src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php
src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml
src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php
src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php
src/Symfony/Component/Validator/Constraints/AllValidator.php
src/Symfony/Component/Validator/Constraints/ChoiceValidator.php
src/Symfony/Component/Validator/Constraints/CollectionValidator.php
src/Symfony/Component/Validator/Constraints/ExpressionValidator.php
src/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/GroupSequenceTest.php
src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/IsbnValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/IssnValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php
src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php
src/Symfony/Component/Validator/Tests/Fixtures/StubGlobalExecutionContext.php
This commit is contained in:
commit
0801a3a8f0
|
@ -16,12 +16,12 @@ use Doctrine\Common\Persistence\ObjectManager;
|
|||
use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity;
|
||||
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
|
||||
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
|
||||
use Symfony\Component\Validator\Validation;
|
||||
use Symfony\Component\Validator\Validator;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
<xsd:attribute name="assets-version" type="xsd:string" />
|
||||
<xsd:attribute name="assets-version-format" type="xsd:string" />
|
||||
<xsd:attribute name="cache" type="xsd:string" />
|
||||
<xsd:attribute name="hinclude-default-template" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="form-resources">
|
||||
|
|
|
@ -56,6 +56,7 @@ $container->loadFromExtension('framework', array(
|
|||
'form' => array(
|
||||
'resources' => array('theme1', 'theme2')
|
||||
),
|
||||
'hinclude_default_template' => 'global_hinclude_template',
|
||||
),
|
||||
'translator' => array(
|
||||
'enabled' => true,
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<framework:mime-type>application/pdf</framework:mime-type>
|
||||
</framework:format>
|
||||
</framework:request>
|
||||
<framework:templating assets-version="SomeVersionScheme" cache="/path/to/cache" >
|
||||
<framework:templating assets-version="SomeVersionScheme" cache="/path/to/cache" hinclude-default-template="global_hinclude_template">
|
||||
<framework:loader>loader.foo</framework:loader>
|
||||
<framework:loader>loader.bar</framework:loader>
|
||||
<framework:engine>php</framework:engine>
|
||||
|
|
|
@ -44,6 +44,7 @@ framework:
|
|||
base_urls: ["http://images1.example.com", "http://images2.example.com"]
|
||||
form:
|
||||
resources: [theme1, theme2]
|
||||
hinclude_default_template: global_hinclude_template
|
||||
translator:
|
||||
enabled: true
|
||||
fallback: fr
|
||||
|
|
|
@ -198,6 +198,7 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||
$this->assertEquals(array('php', 'twig'), $container->getParameter('templating.engines'), '->registerTemplatingConfiguration() sets a templating.engines parameter');
|
||||
|
||||
$this->assertEquals(array('FrameworkBundle:Form', 'theme1', 'theme2'), $container->getParameter('templating.helper.form.resources'), '->registerTemplatingConfiguration() registers the theme and adds the base theme');
|
||||
$this->assertEquals('global_hinclude_template', $container->getParameter('fragment.renderer.hinclude.global_template'), '->registerTemplatingConfiguration() registers the global hinclude.js template');
|
||||
}
|
||||
|
||||
public function testTemplatingAssetsHelperScopeDependsOnPackageArgumentScopes()
|
||||
|
|
|
@ -310,7 +310,7 @@ class ProfilerController
|
|||
}
|
||||
|
||||
/**
|
||||
* Search results.
|
||||
* Renders the search results.
|
||||
*
|
||||
* @param Request $request The current HTTP Request
|
||||
* @param string $token The token
|
||||
|
@ -351,7 +351,7 @@ class ProfilerController
|
|||
}
|
||||
|
||||
/**
|
||||
* Narrow the search bar.
|
||||
* Narrows the search bar.
|
||||
*
|
||||
* @param Request $request The current HTTP Request
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
-webkit-box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.sf-toolbarreset {
|
||||
|
|
|
@ -215,7 +215,11 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
} elseif ('bg' == $match[0]) {
|
||||
$style->setBackground($match[1]);
|
||||
} else {
|
||||
$style->setOption($match[1]);
|
||||
try {
|
||||
$style->setOption($match[1]);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ class OutputFormatterTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
$formatter = new OutputFormatter(true);
|
||||
|
||||
$this->assertEquals("\033[32msome \033[39m\033[32m<tag>\033[39m\033[32m styled \033[39m\033[32m<p>\033[39m\033[32msingle-char tag\033[39m\033[32m</p>\033[39m", $formatter->format('<info>some <tag> styled <p>single-char tag</p></info>'));
|
||||
$this->assertEquals("\033[32msome \033[39m\033[32m<tag>\033[39m\033[32m \033[39m\033[32m<setting=value>\033[39m\033[32m styled \033[39m\033[32m<p>\033[39m\033[32msingle-char tag\033[39m\033[32m</p>\033[39m", $formatter->format('<info>some <tag> <setting=value> styled <p>single-char tag</p></info>'));
|
||||
}
|
||||
|
||||
public function testFormatLongString()
|
||||
|
|
|
@ -831,25 +831,4 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
|||
$this->assertIterator($expected, $finder);
|
||||
$this->assertIteratorInForeach($expected, $finder);
|
||||
}
|
||||
|
||||
public function testNonSeekableStream()
|
||||
{
|
||||
if (!in_array('ftp', stream_get_wrappers())) {
|
||||
$this->markTestSkipped(sprintf('Unavailable stream "%s".', 'ftp'));
|
||||
}
|
||||
|
||||
try {
|
||||
$i = Finder::create()->in('ftp://ftp.mozilla.org/')->depth(0)->getIterator();
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
$this->markTestSkipped(sprintf('Unsupported stream "%s".', 'ftp'));
|
||||
}
|
||||
|
||||
$contains = array(
|
||||
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
|
||||
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'index.html',
|
||||
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
|
||||
);
|
||||
|
||||
$this->assertIteratorInForeach($contains, $i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -502,6 +502,8 @@ class Request
|
|||
*/
|
||||
public function overrideGlobals()
|
||||
{
|
||||
$this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), null, '&')));
|
||||
|
||||
$_GET = $this->query->all();
|
||||
$_POST = $this->request->all();
|
||||
$_SERVER = $this->server->all();
|
||||
|
|
|
@ -62,9 +62,10 @@ class MongoDbSessionHandler implements \SessionHandlerInterface
|
|||
$this->mongo = $mongo;
|
||||
|
||||
$this->options = array_merge(array(
|
||||
'id_field' => '_id',
|
||||
'data_field' => 'data',
|
||||
'time_field' => 'time',
|
||||
'id_field' => '_id',
|
||||
'data_field' => 'data',
|
||||
'time_field' => 'time',
|
||||
'expiry_field' => false,
|
||||
), $options);
|
||||
}
|
||||
|
||||
|
@ -109,6 +110,9 @@ class MongoDbSessionHandler implements \SessionHandlerInterface
|
|||
*
|
||||
* See: http://docs.mongodb.org/manual/tutorial/expire-data/
|
||||
*/
|
||||
if (false !== $this->options['expiry_field']) {
|
||||
return true;
|
||||
}
|
||||
$time = new \MongoDate(time() - $maxlifetime);
|
||||
|
||||
$this->getCollection()->remove(array(
|
||||
|
@ -123,12 +127,27 @@ class MongoDbSessionHandler implements \SessionHandlerInterface
|
|||
*/
|
||||
public function write($sessionId, $data)
|
||||
{
|
||||
$fields = array(
|
||||
$this->options['data_field'] => new \MongoBinData($data, \MongoBinData::BYTE_ARRAY),
|
||||
$this->options['time_field'] => new \MongoDate(),
|
||||
);
|
||||
|
||||
/* Note: As discussed in the gc method of this class. You can utilise
|
||||
* TTL collections in MongoDB 2.2+
|
||||
* We are setting the "expiry_field" as part of the write operation here
|
||||
* You will need to create the index on your collection that expires documents
|
||||
* at that time
|
||||
* e.g.
|
||||
* db.MySessionCollection.ensureIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
|
||||
*/
|
||||
if (false !== $this->options['expiry_field']) {
|
||||
$expiry = new \MongoDate(time() + (int) ini_get('session.gc_maxlifetime'));
|
||||
$fields[$this->options['expiry_field']] = $expiry;
|
||||
}
|
||||
|
||||
$this->getCollection()->update(
|
||||
array($this->options['id_field'] => $sessionId),
|
||||
array('$set' => array(
|
||||
$this->options['data_field'] => new \MongoBinData($data, \MongoBinData::BYTE_ARRAY),
|
||||
$this->options['time_field'] => new \MongoDate(),
|
||||
)),
|
||||
array('$set' => $fields),
|
||||
array('upsert' => true, 'multiple' => false)
|
||||
);
|
||||
|
||||
|
|
|
@ -1012,10 +1012,21 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$request->headers->set('CONTENT_TYPE', 'multipart/form-data');
|
||||
$request->headers->set('CONTENT_LENGTH', 12345);
|
||||
|
||||
$request->overrideGlobals();
|
||||
|
||||
$this->assertArrayHasKey('CONTENT_TYPE', $_SERVER);
|
||||
$this->assertArrayHasKey('CONTENT_LENGTH', $_SERVER);
|
||||
|
||||
$request->initialize(array('foo' => 'bar', 'baz' => 'foo'));
|
||||
$request->query->remove('baz');
|
||||
|
||||
$request->overrideGlobals();
|
||||
|
||||
$this->assertEquals(array('foo' => 'bar'), $_GET);
|
||||
$this->assertEquals('foo=bar', $_SERVER['QUERY_STRING']);
|
||||
$this->assertEquals('foo=bar', $request->server->get('QUERY_STRING'));
|
||||
|
||||
// restore initial $_SERVER array
|
||||
$_SERVER = $server;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
'data_field' => 'data',
|
||||
'time_field' => 'time',
|
||||
'database' => 'sf2-test',
|
||||
'collection' => 'session-test'
|
||||
'collection' => 'session-test',
|
||||
);
|
||||
|
||||
$this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
|
||||
|
@ -100,6 +100,45 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
$that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
|
||||
}
|
||||
|
||||
public function testWriteWhenUsingExpiresField()
|
||||
{
|
||||
$this->options = array(
|
||||
'id_field' => '_id',
|
||||
'data_field' => 'data',
|
||||
'time_field' => 'time',
|
||||
'database' => 'sf2-test',
|
||||
'collection' => 'session-test',
|
||||
'expiry_field' => 'expiresAt'
|
||||
);
|
||||
|
||||
$this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
|
||||
|
||||
$collection = $this->createMongoCollectionMock();
|
||||
|
||||
$this->mongo->expects($this->once())
|
||||
->method('selectCollection')
|
||||
->with($this->options['database'], $this->options['collection'])
|
||||
->will($this->returnValue($collection));
|
||||
|
||||
$that = $this;
|
||||
$data = array();
|
||||
|
||||
$collection->expects($this->once())
|
||||
->method('update')
|
||||
->will($this->returnCallback(function ($criteria, $updateData, $options) use ($that, &$data) {
|
||||
$that->assertEquals(array($that->options['id_field'] => 'foo'), $criteria);
|
||||
$that->assertEquals(array('upsert' => true, 'multiple' => false), $options);
|
||||
|
||||
$data = $updateData['$set'];
|
||||
}));
|
||||
|
||||
$this->assertTrue($this->storage->write('foo', 'bar'));
|
||||
|
||||
$this->assertEquals('bar', $data[$this->options['data_field']]->bin);
|
||||
$that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
|
||||
$that->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
|
||||
}
|
||||
|
||||
public function testReplaceSessionData()
|
||||
{
|
||||
$collection = $this->createMongoCollectionMock();
|
||||
|
@ -154,10 +193,36 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
->method('remove')
|
||||
->will($this->returnCallback(function ($criteria) use ($that) {
|
||||
$that->assertInstanceOf('MongoDate', $criteria[$that->options['time_field']]['$lt']);
|
||||
$that->assertGreaterThanOrEqual(time() - -1, $criteria[$that->options['time_field']]['$lt']->sec);
|
||||
$that->assertGreaterThanOrEqual(time() - 1, $criteria[$that->options['time_field']]['$lt']->sec);
|
||||
}));
|
||||
|
||||
$this->assertTrue($this->storage->gc(-1));
|
||||
$this->assertTrue($this->storage->gc(1));
|
||||
}
|
||||
|
||||
public function testGcWhenUsingExpiresField()
|
||||
{
|
||||
$this->options = array(
|
||||
'id_field' => '_id',
|
||||
'data_field' => 'data',
|
||||
'time_field' => 'time',
|
||||
'database' => 'sf2-test',
|
||||
'collection' => 'session-test',
|
||||
'expiry_field' => 'expiresAt'
|
||||
);
|
||||
|
||||
$this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
|
||||
|
||||
$collection = $this->createMongoCollectionMock();
|
||||
|
||||
$this->mongo->expects($this->never())
|
||||
->method('selectCollection');
|
||||
|
||||
$that = $this;
|
||||
|
||||
$collection->expects($this->never())
|
||||
->method('remove');
|
||||
|
||||
$this->assertTrue($this->storage->gc(1));
|
||||
}
|
||||
|
||||
public function testGetConnection()
|
||||
|
|
|
@ -149,25 +149,6 @@ class StopwatchEventTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(0, $event->getStartTime(), null, self::DELTA);
|
||||
}
|
||||
|
||||
public function testEndTime()
|
||||
{
|
||||
$event = new StopwatchEvent(microtime(true) * 1000);
|
||||
$this->assertEquals(0, $event->getEndTime());
|
||||
|
||||
$event = new StopwatchEvent(microtime(true) * 1000);
|
||||
$event->start();
|
||||
$this->assertEquals(0, $event->getEndTime());
|
||||
|
||||
$event = new StopwatchEvent(microtime(true) * 1000);
|
||||
$event->start();
|
||||
usleep(100000);
|
||||
$event->stop();
|
||||
$event->start();
|
||||
usleep(100000);
|
||||
$event->stop();
|
||||
$this->assertEquals(200, $event->getEndTime(), null, self::DELTA);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
|
|
|
@ -80,19 +80,6 @@ class StopwatchTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(200, $event->getDuration(), null, self::DELTA);
|
||||
}
|
||||
|
||||
public function testLap()
|
||||
{
|
||||
$stopwatch = new Stopwatch();
|
||||
$stopwatch->start('foo', 'cat');
|
||||
usleep(100000);
|
||||
$event = $stopwatch->lap('foo');
|
||||
usleep(100000);
|
||||
$stopwatch->stop('foo');
|
||||
|
||||
$this->assertInstanceof('Symfony\Component\Stopwatch\StopwatchEvent', $event);
|
||||
$this->assertEquals(200, $event->getDuration(), null, self::DELTA);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
|
|
|
@ -20,6 +20,21 @@ namespace Symfony\Component\Validator;
|
|||
*/
|
||||
abstract class ConstraintValidator implements ConstraintValidatorInterface
|
||||
{
|
||||
/**
|
||||
* Whether to format {@link \DateTime} objects as RFC-3339 dates
|
||||
* ("Y-m-d H:i:s").
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const PRETTY_DATE = 1;
|
||||
|
||||
/**
|
||||
* Whether to cast objects with a "__toString()" method to strings.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const OBJECT_TO_STRING = 2;
|
||||
|
||||
/**
|
||||
* @var ExecutionContextInterface
|
||||
*/
|
||||
|
@ -66,15 +81,15 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface
|
|||
* won't know what an "object", "array" or "resource" is and will be
|
||||
* confused by the violation message.
|
||||
*
|
||||
* @param mixed $value The value to format as string
|
||||
* @param bool $prettyDateTime Whether to format {@link \DateTime}
|
||||
* objects as RFC-3339 dates ("Y-m-d H:i:s")
|
||||
* @param mixed $value The value to format as string
|
||||
* @param integer $format A bitwise combination of the format
|
||||
* constants in this class
|
||||
*
|
||||
* @return string The string representation of the passed value
|
||||
*/
|
||||
protected function formatValue($value, $prettyDateTime = false)
|
||||
protected function formatValue($value, $format = 0)
|
||||
{
|
||||
if ($prettyDateTime && $value instanceof \DateTime) {
|
||||
if (($format & self::PRETTY_DATE) && $value instanceof \DateTime) {
|
||||
if (class_exists('IntlDateFormatter')) {
|
||||
$locale = \Locale::getDefault();
|
||||
$formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT);
|
||||
|
@ -86,6 +101,10 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface
|
|||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
if ($format & self::OBJECT_TO_STRING && method_exists($value, '__toString')) {
|
||||
return $value->__toString();
|
||||
}
|
||||
|
||||
return 'object';
|
||||
}
|
||||
|
||||
|
@ -122,18 +141,18 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface
|
|||
* Each of the values is converted to a string using
|
||||
* {@link formatValue()}. The values are then concatenated with commas.
|
||||
*
|
||||
* @param array $values A list of values
|
||||
* @param bool $prettyDateTime Whether to format {@link \DateTime}
|
||||
* objects as RFC-3339 dates ("Y-m-d H:i:s")
|
||||
* @param array $values A list of values
|
||||
* @param integer $format A bitwise combination of the format
|
||||
* constants in this class
|
||||
*
|
||||
* @return string The string representation of the value list
|
||||
*
|
||||
* @see formatValue()
|
||||
*/
|
||||
protected function formatValues(array $values, $prettyDateTime = false)
|
||||
protected function formatValues(array $values, $format = 0)
|
||||
{
|
||||
foreach ($values as $key => $value) {
|
||||
$values[$key] = $this->formatValue($value, $prettyDateTime);
|
||||
$values[$key] = $this->formatValue($value, $format);
|
||||
}
|
||||
|
||||
return implode(', ', $values);
|
||||
|
|
|
@ -37,8 +37,8 @@ abstract class AbstractComparisonValidator extends ConstraintValidator
|
|||
|
||||
if (!$this->compareValues($value, $constraint->value)) {
|
||||
$this->context->addViolation($constraint->message, array(
|
||||
'{{ value }}' => $this->formatValue($value, true),
|
||||
'{{ compared_value }}' => $this->formatValue($constraint->value, true),
|
||||
'{{ 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)
|
||||
));
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ class UrlValidator extends ConstraintValidator
|
|||
{
|
||||
const PATTERN = '~^
|
||||
(%s):// # protocol
|
||||
(([\pL\pN-]+:)?([\pL\pN-]+)@)? # basic auth
|
||||
(
|
||||
([\pL\pN\pS-\.])+(\.?([\pL]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
|
||||
| # or
|
||||
|
|
|
@ -59,6 +59,7 @@ class EqualToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||
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 ComparisonTest_Class(4), 'object', new ComparisonTest_Class(5), 'object', __NAMESPACE__.'\ComparisonTest_Class'), );
|
||||
array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,36 +95,54 @@ abstract class FileValidatorTest extends AbstractConstraintValidatorTest
|
|||
|
||||
public function provideMaxSizeExceededTests()
|
||||
{
|
||||
// We have various interesting limit - size combinations to test.
|
||||
// Assume a limit of 1000 bytes (1 kB). Then the following table
|
||||
// lists the violation messages for different file sizes:
|
||||
|
||||
// -----------+--------------------------------------------------------
|
||||
// Size | Violation Message
|
||||
// -----------+--------------------------------------------------------
|
||||
// 1000 bytes | No violation
|
||||
// 1001 bytes | "Size of 1001 bytes exceeded limit of 1000 bytes"
|
||||
// 1004 bytes | "Size of 1004 bytes exceeded limit of 1000 bytes"
|
||||
// | NOT: "Size of 1 kB exceeded limit of 1 kB"
|
||||
// 1005 bytes | "Size of 1.01 kB exceeded limit of 1 kB"
|
||||
// -----------+--------------------------------------------------------
|
||||
|
||||
// As you see, we have two interesting borders:
|
||||
|
||||
// 1000/1001 - The border as of which a violation occurs
|
||||
// 1004/1005 - The border as of which the message can be rounded to kB
|
||||
|
||||
// Analogous for kB/MB.
|
||||
|
||||
// Prior to Symfony 2.5, violation messages are always displayed in the
|
||||
// same unit used to specify the limit.
|
||||
|
||||
// As of Symfony 2.5, the above logic is implemented.
|
||||
return array(
|
||||
array(11, 10, '11', '10', 'bytes'),
|
||||
// limit in bytes
|
||||
array(1001, 1000, '1001', '1000', 'bytes'),
|
||||
array(1004, 1000, '1004', '1000', 'bytes'),
|
||||
array(1005, 1000, '1.01', '1', 'kB'),
|
||||
|
||||
array(ceil(1.005*1000), ceil(1.005*1000) - 1, '1005', '1004', 'bytes'),
|
||||
array(ceil(1.005*1000*1000), ceil(1.005*1000*1000) - 1, '1005000', '1004999', 'bytes'),
|
||||
array(1000001, 1000000, '1000001', '1000000', 'bytes'),
|
||||
array(1004999, 1000000, '1005', '1000', 'kB'),
|
||||
array(1005000, 1000000, '1.01', '1', 'MB'),
|
||||
|
||||
// round(size) == 1.01kB, limit == 1kB
|
||||
array(ceil(1.005*1000), 1000, '1.01', '1', 'kB'),
|
||||
array(ceil(1.005*1000), '1k', '1.01', '1', 'kB'),
|
||||
// limit in kB
|
||||
array(1001, '1k', '1001', '1000', 'bytes'),
|
||||
array(1004, '1k', '1004', '1000', 'bytes'),
|
||||
array(1005, '1k', '1.01', '1', 'kB'),
|
||||
|
||||
// round(size) == 1kB, limit == 1kB -> use bytes
|
||||
array(ceil(1.004*1000), 1000, '1004', '1000', 'bytes'),
|
||||
array(ceil(1.004*1000), '1k', '1004', '1000', 'bytes'),
|
||||
array(1000001, '1000k', '1000001', '1000000', 'bytes'),
|
||||
array(1004999, '1000k', '1005', '1000', 'kB'),
|
||||
array(1005000, '1000k', '1.01', '1', 'MB'),
|
||||
|
||||
array(1000 + 1, 1000, '1001', '1000', 'bytes'),
|
||||
array(1000 + 1, '1k', '1001', '1000', 'bytes'),
|
||||
|
||||
// round(size) == 1.01MB, limit == 1MB
|
||||
array(ceil(1.005*1000*1000), 1000*1000, '1.01', '1', 'MB'),
|
||||
array(ceil(1.005*1000*1000), '1000k', '1.01', '1', 'MB'),
|
||||
array(ceil(1.005*1000*1000), '1M', '1.01', '1', 'MB'),
|
||||
|
||||
// round(size) == 1MB, limit == 1MB -> use kB
|
||||
array(ceil(1.004*1000*1000), 1000*1000, '1004', '1000', 'kB'),
|
||||
array(ceil(1.004*1000*1000), '1000k', '1004', '1000', 'kB'),
|
||||
array(ceil(1.004*1000*1000), '1M', '1004', '1000', 'kB'),
|
||||
|
||||
array(1000*1000 + 1, 1000*1000, '1000001', '1000000', 'bytes'),
|
||||
array(1000*1000 + 1, '1000k', '1000001', '1000000', 'bytes'),
|
||||
array(1000*1000 + 1, '1M', '1000001', '1000000', 'bytes'),
|
||||
// limit in MB
|
||||
array(1000001, '1M', '1000001', '1000000', 'bytes'),
|
||||
array(1004999, '1M', '1005', '1000', 'kB'),
|
||||
array(1005000, '1M', '1.01', '1', 'MB'),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -155,14 +173,16 @@ abstract class FileValidatorTest extends AbstractConstraintValidatorTest
|
|||
public function provideMaxSizeNotExceededTests()
|
||||
{
|
||||
return array(
|
||||
array(10, 10),
|
||||
array(9, 10),
|
||||
// limit in bytes
|
||||
array(1000, 1000),
|
||||
array(1000000, 1000000),
|
||||
|
||||
// limit in kB
|
||||
array(1000, '1k'),
|
||||
array(1000 - 1, '1k'),
|
||||
array(1000000, '1000k'),
|
||||
|
||||
array(1000*1000, '1M'),
|
||||
array(1000*1000 - 1, '1M'),
|
||||
// limit in MB
|
||||
array(1000000, '1M'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,8 +59,8 @@ class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase
|
|||
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 ComparisonTest_Class(5), 'object', new ComparisonTest_Class(5), 'object', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
array(new ComparisonTest_Class(5), 'object', new ComparisonTest_Class(5), 'object', __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('22', '"22"', '333', '"333"', 'string'),
|
||||
array('22', '"22"', '22', '"22"', 'string')
|
||||
);
|
||||
|
|
|
@ -63,7 +63,7 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||
array('22', '"22"', '333', '"333"', 'string'),
|
||||
array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', 'DateTime'),
|
||||
array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('1999-01-01'), 'Jan 1, 1999, 12:00 AM', 'DateTime'),
|
||||
array(new ComparisonTest_Class(4), 'object', new ComparisonTest_Class(5), 'object', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase
|
|||
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 ComparisonTest_Class(5), 'object', new ComparisonTest_Class(4), 'object', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(4), '4', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
array('c', '"c"', 'b', '"b"', 'string')
|
||||
);
|
||||
}
|
||||
|
|
|
@ -59,8 +59,8 @@ class LessThanValidatorTest extends AbstractComparisonValidatorTestCase
|
|||
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 ComparisonTest_Class(5), 'object', new ComparisonTest_Class(5), 'object', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
array(new ComparisonTest_Class(6), 'object', new ComparisonTest_Class(5), 'object', __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('333', '"333"', '22', '"22"', 'string'),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||
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 ComparisonTest_Class(5), 'object', new ComparisonTest_Class(5), 'object', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ class NotIdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
|
|||
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, 'object', $object, 'object', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
array($object, '2', $object, '2', __NAMESPACE__.'\ComparisonTest_Class'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,8 @@ class UrlValidatorTest extends AbstractConstraintValidatorTest
|
|||
array('http://xn--espaa-rta.xn--ca-ol-fsay5a/'),
|
||||
array('http://xn--d1abbgf6aiiy.xn--p1ai/'),
|
||||
array('http://☎.com/'),
|
||||
array('http://username:password@symfony.com'),
|
||||
array('http://user-name@symfony.com'),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -145,6 +147,10 @@ class UrlValidatorTest extends AbstractConstraintValidatorTest
|
|||
array('ftp://[::1]/'),
|
||||
array('http://[::1'),
|
||||
array('http://hello.☎/'),
|
||||
array('http://:password@symfony.com'),
|
||||
array('http://:password@@symfony.com'),
|
||||
array('http://username:passwordsymfony.com'),
|
||||
array('http://usern@me:password@symfony.com'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Reference in New Issue