feature #26484 [Validator] String normalization options for string-based validators (renan-taranto)
This PR was merged into the 4.3-dev branch.
Discussion
----------
[Validator] String normalization options for string-based validators
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #26239
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/9433
Todo:
- [x] Document the new options
- [x] Update Doc PR
Add trimming options to the string constraints.
Commits
-------
708d759b8d
[Validator] String normalization options for string-based validators
This commit is contained in:
commit
b14d5cd358
@ -8,8 +8,13 @@ CHANGELOG
|
||||
* added UATP cards support to `CardSchemeValidator`
|
||||
* added option `allowNull` to NotBlank constraint
|
||||
* added `Json` constraint
|
||||
<<<<<<< HEAD
|
||||
* added `Unique` constraint
|
||||
|
||||
=======
|
||||
* added a new `normalizer` option to the string constraints and to the `NotBlank` constraint
|
||||
|
||||
>>>>>>> pull/26484
|
||||
4.2.0
|
||||
-----
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Egulias\EmailValidator\EmailValidator as StrictEmailValidator;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Validator\Exception\LogicException;
|
||||
|
||||
/**
|
||||
@ -73,6 +74,7 @@ class Email extends Constraint
|
||||
*/
|
||||
public $strict;
|
||||
public $mode;
|
||||
public $normalizer;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
@ -89,7 +91,7 @@ class Email extends Constraint
|
||||
}
|
||||
|
||||
if (\is_array($options) && \array_key_exists('mode', $options) && !\in_array($options['mode'], self::$validationModes, true)) {
|
||||
throw new \InvalidArgumentException('The "mode" parameter value is not valid.');
|
||||
throw new InvalidArgumentException('The "mode" parameter value is not valid.');
|
||||
}
|
||||
|
||||
parent::__construct($options);
|
||||
@ -98,5 +100,9 @@ class Email extends Constraint
|
||||
// throw new LogicException(sprintf('The "egulias/email-validator" component is required to use the "%s" constraint in strict mode.', __CLASS__));
|
||||
@trigger_error(sprintf('Using the "%s" constraint in strict mode without the "egulias/email-validator" component installed is deprecated since Symfony 4.2.', __CLASS__), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,10 @@ class EmailValidator extends ConstraintValidator
|
||||
|
||||
$value = (string) $value;
|
||||
|
||||
if (null !== $constraint->normalizer) {
|
||||
$value = ($constraint->normalizer)($value);
|
||||
}
|
||||
|
||||
if (null !== $constraint->strict) {
|
||||
@trigger_error(sprintf('The %s::$strict property is deprecated since Symfony 4.1. Use %s::mode="%s" instead.', Email::class, Email::class, Email::VALIDATION_MODE_STRICT), E_USER_DEPRECATED);
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||
use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Validates that a value is a valid IP address.
|
||||
@ -72,6 +73,8 @@ class Ip extends Constraint
|
||||
|
||||
public $message = 'This is not a valid IP address.';
|
||||
|
||||
public $normalizer;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -82,5 +85,9 @@ class Ip extends Constraint
|
||||
if (!\in_array($this->version, self::$versions)) {
|
||||
throw new ConstraintDefinitionException(sprintf('The option "version" must be one of "%s"', implode('", "', self::$versions)));
|
||||
}
|
||||
|
||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,10 @@ class IpValidator extends ConstraintValidator
|
||||
|
||||
$value = (string) $value;
|
||||
|
||||
if (null !== $constraint->normalizer) {
|
||||
$value = ($constraint->normalizer)($value);
|
||||
}
|
||||
|
||||
switch ($constraint->version) {
|
||||
case Ip::V4:
|
||||
$flag = FILTER_FLAG_IPV4;
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Validator\Exception\MissingOptionsException;
|
||||
|
||||
/**
|
||||
@ -39,6 +40,7 @@ class Length extends Constraint
|
||||
public $max;
|
||||
public $min;
|
||||
public $charset = 'UTF-8';
|
||||
public $normalizer;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
@ -54,5 +56,9 @@ class Length extends Constraint
|
||||
if (null === $this->min && null === $this->max) {
|
||||
throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), ['min', 'max']);
|
||||
}
|
||||
|
||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,10 @@ class LengthValidator extends ConstraintValidator
|
||||
|
||||
$stringValue = (string) $value;
|
||||
|
||||
if (null !== $constraint->normalizer) {
|
||||
$stringValue = ($constraint->normalizer)($stringValue);
|
||||
}
|
||||
|
||||
if (!$invalidCharset = !@mb_check_encoding($stringValue, $constraint->charset)) {
|
||||
$length = mb_strlen($stringValue, $constraint->charset);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
@ -30,4 +31,14 @@ class NotBlank extends Constraint
|
||||
|
||||
public $message = 'This value should not be blank.';
|
||||
public $allowNull = false;
|
||||
public $normalizer;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ class NotBlankValidator extends ConstraintValidator
|
||||
return;
|
||||
}
|
||||
|
||||
if (\is_string($value) && null !== $constraint->normalizer) {
|
||||
$value = ($constraint->normalizer)($value);
|
||||
}
|
||||
|
||||
if (false === $value || (empty($value) && '0' != $value)) {
|
||||
$this->context->buildViolation($constraint->message)
|
||||
->setParameter('{{ value }}', $this->formatValue($value))
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
@ -31,6 +32,16 @@ class Regex extends Constraint
|
||||
public $pattern;
|
||||
public $htmlPattern;
|
||||
public $match = true;
|
||||
public $normalizer;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -43,6 +43,10 @@ class RegexValidator extends ConstraintValidator
|
||||
|
||||
$value = (string) $value;
|
||||
|
||||
if (null !== $constraint->normalizer) {
|
||||
$value = ($constraint->normalizer)($value);
|
||||
}
|
||||
|
||||
if ($constraint->match xor preg_match($constraint->pattern, $value)) {
|
||||
$this->context->buildViolation($constraint->message)
|
||||
->setParameter('{{ value }}', $this->formatValue($value))
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
@ -105,6 +106,7 @@ class Url extends Constraint
|
||||
*/
|
||||
public $checkDNS = self::CHECK_DNS_TYPE_NONE;
|
||||
public $relativeProtocol = false;
|
||||
public $normalizer;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
@ -118,5 +120,9 @@ class Url extends Constraint
|
||||
}
|
||||
|
||||
parent::__construct($options);
|
||||
|
||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,10 @@ class UrlValidator extends ConstraintValidator
|
||||
return;
|
||||
}
|
||||
|
||||
if (null !== $constraint->normalizer) {
|
||||
$value = ($constraint->normalizer)($value);
|
||||
}
|
||||
|
||||
$pattern = $constraint->relativeProtocol ? str_replace('(%s):', '(?:(%s):)?', static::PATTERN) : static::PATTERN;
|
||||
$pattern = sprintf($pattern, implode('|', $constraint->protocols));
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
@ -74,4 +75,15 @@ class Uuid extends Constraint
|
||||
self::V4_RANDOM,
|
||||
self::V5_SHA1,
|
||||
];
|
||||
|
||||
public $normalizer;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,10 @@ class UuidValidator extends ConstraintValidator
|
||||
|
||||
$value = (string) $value;
|
||||
|
||||
if (null !== $constraint->normalizer) {
|
||||
$value = ($constraint->normalizer)($value);
|
||||
}
|
||||
|
||||
if ($constraint->strict) {
|
||||
$this->validateStrict($value, $constraint);
|
||||
|
||||
|
@ -35,11 +35,36 @@ class EmailTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "mode" parameter value is not valid.
|
||||
*/
|
||||
public function testUnknownModesTriggerException()
|
||||
{
|
||||
new Email(['mode' => 'Unknown Mode']);
|
||||
}
|
||||
|
||||
public function testNormalizerCanBeSet()
|
||||
{
|
||||
$email = new Email(['normalizer' => 'trim']);
|
||||
|
||||
$this->assertEquals('trim', $email->normalizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
|
||||
*/
|
||||
public function testInvalidNormalizerThrowsException()
|
||||
{
|
||||
new Email(['normalizer' => 'Unknown Callable']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
|
||||
*/
|
||||
public function testInvalidNormalizerObjectThrowsException()
|
||||
{
|
||||
new Email(['normalizer' => new \stdClass()]);
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +94,28 @@ class EmailValidatorTest extends ConstraintValidatorTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidEmailsWithWhitespaces
|
||||
*/
|
||||
public function testValidNormalizedEmails($email)
|
||||
{
|
||||
$this->validator->validate($email, new Email(['normalizer' => 'trim']));
|
||||
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
public function getValidEmailsWithWhitespaces()
|
||||
{
|
||||
return [
|
||||
["\x20example@example.co.uk\x20"],
|
||||
["\x09\x09example@example.co..uk\x09\x09"],
|
||||
["\x0A{}~!@!@£$%%^&*().!@£$%^&*()\x0A"],
|
||||
["\x0D\x0Dexample@example.co..uk\x0D\x0D"],
|
||||
["\x00example@-example.com"],
|
||||
["example@example.com\x0B\x0B"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidEmailsHtml5
|
||||
*/
|
||||
|
46
src/Symfony/Component/Validator/Tests/Constraints/IpTest.php
Normal file
46
src/Symfony/Component/Validator/Tests/Constraints/IpTest.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Validator\Constraints\Ip;
|
||||
|
||||
/**
|
||||
* @author Renan Taranto <renantaranto@gmail.com>
|
||||
*/
|
||||
class IpTest extends TestCase
|
||||
{
|
||||
public function testNormalizerCanBeSet()
|
||||
{
|
||||
$ip = new Ip(['normalizer' => 'trim']);
|
||||
|
||||
$this->assertEquals('trim', $ip->normalizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
|
||||
*/
|
||||
public function testInvalidNormalizerThrowsException()
|
||||
{
|
||||
new Ip(['normalizer' => 'Unknown Callable']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
|
||||
*/
|
||||
public function testInvalidNormalizerObjectThrowsException()
|
||||
{
|
||||
new Ip(['normalizer' => new \stdClass()]);
|
||||
}
|
||||
}
|
@ -80,6 +80,31 @@ class IpValidatorTest extends ConstraintValidatorTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidIpsV4WithWhitespaces
|
||||
*/
|
||||
public function testValidIpsV4WithWhitespaces($ip)
|
||||
{
|
||||
$this->validator->validate($ip, new Ip([
|
||||
'version' => Ip::V4,
|
||||
'normalizer' => 'trim',
|
||||
]));
|
||||
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
public function getValidIpsV4WithWhitespaces()
|
||||
{
|
||||
return [
|
||||
["\x200.0.0.0"],
|
||||
["\x09\x0910.0.0.0"],
|
||||
["123.45.67.178\x0A"],
|
||||
["172.16.0.0\x0D\x0D"],
|
||||
["\x00192.168.1.0\x00"],
|
||||
["\x0B\x0B224.0.0.1\x0B\x0B"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidIpsV6
|
||||
*/
|
||||
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
|
||||
/**
|
||||
* @author Renan Taranto <renantaranto@gmail.com>
|
||||
*/
|
||||
class LengthTest extends TestCase
|
||||
{
|
||||
public function testNormalizerCanBeSet()
|
||||
{
|
||||
$length = new Length(['min' => 0, 'max' => 10, 'normalizer' => 'trim']);
|
||||
|
||||
$this->assertEquals('trim', $length->normalizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
|
||||
*/
|
||||
public function testInvalidNormalizerThrowsException()
|
||||
{
|
||||
new Length(['min' => 0, 'max' => 10, 'normalizer' => 'Unknown Callable']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
|
||||
*/
|
||||
public function testInvalidNormalizerObjectThrowsException()
|
||||
{
|
||||
new Length(['min' => 0, 'max' => 10, 'normalizer' => new \stdClass()]);
|
||||
}
|
||||
}
|
@ -92,6 +92,18 @@ class LengthValidatorTest extends ConstraintValidatorTestCase
|
||||
];
|
||||
}
|
||||
|
||||
public function getThreeCharactersWithWhitespaces()
|
||||
{
|
||||
return [
|
||||
["\x20ccc"],
|
||||
["\x09c\x09c"],
|
||||
["\x0Accc\x0A"],
|
||||
["ccc\x0D\x0D"],
|
||||
["\x00ccc\x00"],
|
||||
["\x0Bc\x0Bc\x0B"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getFiveOrMoreCharacters
|
||||
*/
|
||||
@ -125,6 +137,17 @@ class LengthValidatorTest extends ConstraintValidatorTestCase
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getThreeCharactersWithWhitespaces
|
||||
*/
|
||||
public function testValidNormalizedValues($value)
|
||||
{
|
||||
$constraint = new Length(['min' => 3, 'max' => 3, 'normalizer' => 'trim']);
|
||||
$this->validator->validate($value, $constraint);
|
||||
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getThreeOrLessCharacters
|
||||
*/
|
||||
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
|
||||
/**
|
||||
* @author Renan Taranto <renantaranto@gmail.com>
|
||||
*/
|
||||
class NotBlankTest extends TestCase
|
||||
{
|
||||
public function testNormalizerCanBeSet()
|
||||
{
|
||||
$notBlank = new NotBlank(['normalizer' => 'trim']);
|
||||
|
||||
$this->assertEquals('trim', $notBlank->normalizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
|
||||
*/
|
||||
public function testInvalidNormalizerThrowsException()
|
||||
{
|
||||
new NotBlank(['normalizer' => 'Unknown Callable']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
|
||||
*/
|
||||
public function testInvalidNormalizerObjectThrowsException()
|
||||
{
|
||||
new NotBlank(['normalizer' => new \stdClass()]);
|
||||
}
|
||||
}
|
@ -124,4 +124,34 @@ class NotBlankValidatorTest extends ConstraintValidatorTestCase
|
||||
->setCode(NotBlank::IS_BLANK_ERROR)
|
||||
->assertRaised();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getWhitespaces
|
||||
*/
|
||||
public function testNormalizedStringIsInvalid($value)
|
||||
{
|
||||
$constraint = new NotBlank([
|
||||
'message' => 'myMessage',
|
||||
'normalizer' => 'trim',
|
||||
]);
|
||||
|
||||
$this->validator->validate($value, $constraint);
|
||||
|
||||
$this->buildViolation('myMessage')
|
||||
->setParameter('{{ value }}', '""')
|
||||
->setCode(NotBlank::IS_BLANK_ERROR)
|
||||
->assertRaised();
|
||||
}
|
||||
|
||||
public function getWhitespaces()
|
||||
{
|
||||
return [
|
||||
["\x20"],
|
||||
["\x09\x09"],
|
||||
["\x0A"],
|
||||
["\x0D\x0D"],
|
||||
["\x00"],
|
||||
["\x0B\x0B"],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -85,4 +85,29 @@ class RegexTest extends TestCase
|
||||
$this->assertSame('((?![0-9]$|[a-z]+).)*', $constraint->pattern);
|
||||
$this->assertSame('foobar', $constraint->getHtmlPattern());
|
||||
}
|
||||
|
||||
public function testNormalizerCanBeSet()
|
||||
{
|
||||
$regex = new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => 'trim']);
|
||||
|
||||
$this->assertEquals('trim', $regex->normalizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
|
||||
*/
|
||||
public function testInvalidNormalizerThrowsException()
|
||||
{
|
||||
new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => 'Unknown Callable']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
|
||||
*/
|
||||
public function testInvalidNormalizerObjectThrowsException()
|
||||
{
|
||||
new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => new \stdClass()]);
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,17 @@ class RegexValidatorTest extends ConstraintValidatorTestCase
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidValuesWithWhitespaces
|
||||
*/
|
||||
public function testValidValuesWithWhitespaces($value)
|
||||
{
|
||||
$constraint = new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => 'trim']);
|
||||
$this->validator->validate($value, $constraint);
|
||||
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
public function getValidValues()
|
||||
{
|
||||
return [
|
||||
@ -71,6 +82,18 @@ class RegexValidatorTest extends ConstraintValidatorTestCase
|
||||
];
|
||||
}
|
||||
|
||||
public function getValidValuesWithWhitespaces()
|
||||
{
|
||||
return [
|
||||
["\x207"],
|
||||
["\x09\x09070707\x09\x09"],
|
||||
["70707\x0A"],
|
||||
["7\x0D\x0D"],
|
||||
["\x00070707\x00"],
|
||||
["\x0B\x0B70707\x0B\x0B"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getInvalidValues
|
||||
*/
|
||||
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Validator\Constraints\Url;
|
||||
|
||||
/**
|
||||
* @author Renan Taranto <renantaranto@gmail.com>
|
||||
*/
|
||||
class UrlTest extends TestCase
|
||||
{
|
||||
public function testNormalizerCanBeSet()
|
||||
{
|
||||
$url = new Url(['normalizer' => 'trim']);
|
||||
|
||||
$this->assertEquals('trim', $url->normalizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
|
||||
*/
|
||||
public function testInvalidNormalizerThrowsException()
|
||||
{
|
||||
new Url(['normalizer' => 'Unknown Callable']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
|
||||
*/
|
||||
public function testInvalidNormalizerObjectThrowsException()
|
||||
{
|
||||
new Url(['normalizer' => new \stdClass()]);
|
||||
}
|
||||
}
|
@ -65,6 +65,16 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidUrlsWithWhitespaces
|
||||
*/
|
||||
public function testValidUrlsWithWhitespaces($url)
|
||||
{
|
||||
$this->validator->validate($url, new Url(['normalizer' => 'trim']));
|
||||
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidRelativeUrls
|
||||
* @dataProvider getValidUrls
|
||||
@ -155,6 +165,18 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
|
||||
];
|
||||
}
|
||||
|
||||
public function getValidUrlsWithWhitespaces()
|
||||
{
|
||||
return [
|
||||
["\x20http://www.google.com"],
|
||||
["\x09\x09http://www.google.com."],
|
||||
["http://symfony.fake/blog/\x0A"],
|
||||
["http://symfony.com/search?type=&q=url+validator\x0D\x0D"],
|
||||
["\x00https://google.com:80\x00"],
|
||||
["\x0B\x0Bhttp://username:password@symfony.com\x0B\x0B"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getInvalidUrls
|
||||
*/
|
||||
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Validator\Constraints\Uuid;
|
||||
|
||||
/**
|
||||
* @author Renan Taranto <renantaranto@gmail.com>
|
||||
*/
|
||||
class UuidTest extends TestCase
|
||||
{
|
||||
public function testNormalizerCanBeSet()
|
||||
{
|
||||
$uuid = new Uuid(['normalizer' => 'trim']);
|
||||
|
||||
$this->assertEquals('trim', $uuid->normalizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
|
||||
*/
|
||||
public function testInvalidNormalizerThrowsException()
|
||||
{
|
||||
new Uuid(['normalizer' => 'Unknown Callable']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
|
||||
*/
|
||||
public function testInvalidNormalizerObjectThrowsException()
|
||||
{
|
||||
new Uuid(['normalizer' => new \stdClass()]);
|
||||
}
|
||||
}
|
@ -85,6 +85,34 @@ class UuidValidatorTest extends ConstraintValidatorTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidStrictUuidsWithWhitespaces
|
||||
*/
|
||||
public function testValidStrictUuidsWithWhitespaces($uuid, $versions = null)
|
||||
{
|
||||
$constraint = new Uuid(['normalizer' => 'trim']);
|
||||
|
||||
if (null !== $versions) {
|
||||
$constraint->versions = $versions;
|
||||
}
|
||||
|
||||
$this->validator->validate($uuid, $constraint);
|
||||
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
public function getValidStrictUuidsWithWhitespaces()
|
||||
{
|
||||
return [
|
||||
["\x20216fff40-98d9-11e3-a5e2-0800200c9a66"], // Version 1 UUID in lowercase
|
||||
["\x09\x09216fff40-98d9-11e3-a5e2-0800200c9a66", [Uuid::V1_MAC]],
|
||||
["216FFF40-98D9-11E3-A5E2-0800200C9A66\x0A"], // Version 1 UUID in UPPERCASE
|
||||
["456daefb-5aa6-41b5-8dbc-068b05a8b201\x0D\x0D"], // Version 4 UUID in lowercase
|
||||
["\x00456daEFb-5AA6-41B5-8DBC-068B05A8B201\x00"], // Version 4 UUID in mixed case
|
||||
["\x0B\x0B456daEFb-5AA6-41B5-8DBC-068B05A8B201\x0B\x0B", [Uuid::V4_RANDOM]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getInvalidStrictUuids
|
||||
*/
|
||||
|
Reference in New Issue
Block a user