bug #12004 [Form] Fixed ValidatorTypeGuesser to guess properties without constraints not to be required (webmozart)
This PR was merged into the 2.3 branch.
Discussion
----------
[Form] Fixed ValidatorTypeGuesser to guess properties without constraints not to be required
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #6645
| License | MIT
| Doc PR | -
Consider the following entity:
```php
class Author
{
/**
* @Assert\NotBlank
*/
private $name;
private $age;
}
```
Right now, the "required" HTML attribute is set for both fields (since the default value of the "required" option is true). IMO this is wrong.
With this fix, the ValidatorTypeGuesser guesses `false` for the "required" option unless a NotNull/NotBlank constraint is present.
Commits
-------
fd77b09
[Form] Fixed ValidatorTypeGuesser to guess properties without constraints not to be required
This commit is contained in:
commit
bc8ee6f497
@ -1,9 +1,8 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
|
||||||
2.3.0
|
2.3.0
|
||||||
------
|
-----
|
||||||
|
|
||||||
* deprecated FormPerformanceTestCase and FormIntegrationTestCase in the Symfony\Component\Form\Tests namespace and moved them to the Symfony\Component\Form\Test namespace
|
* deprecated FormPerformanceTestCase and FormIntegrationTestCase in the Symfony\Component\Form\Tests namespace and moved them to the Symfony\Component\Form\Test namespace
|
||||||
* deprecated TypeTestCase in the Symfony\Component\Form\Tests\Extension\Core\Type namespace and moved it to the Symfony\Component\Form\Test namespace
|
* deprecated TypeTestCase in the Symfony\Component\Form\Tests\Extension\Core\Type namespace and moved it to the Symfony\Component\Form\Test namespace
|
||||||
|
@ -276,11 +276,11 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (null !== $defaultValue) {
|
if (null !== $defaultValue) {
|
||||||
$guesses[] = new ValueGuess($defaultValue, Guess::LOW_CONFIDENCE);
|
$guesses[] = new ValueGuess($defaultValue, Guess::LOW_CONFIDENCE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return Guess::getBestGuess($guesses);
|
return Guess::getBestGuess($guesses);
|
||||||
}
|
}
|
||||||
|
@ -13,32 +13,91 @@ namespace Symfony\Component\Form\Tests\Extension\Validator;
|
|||||||
|
|
||||||
use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser;
|
use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser;
|
||||||
use Symfony\Component\Form\Guess\Guess;
|
use Symfony\Component\Form\Guess\Guess;
|
||||||
|
use Symfony\Component\Form\Guess\ValueGuess;
|
||||||
|
use Symfony\Component\Validator\Constraints\Email;
|
||||||
use Symfony\Component\Validator\Constraints\Length;
|
use Symfony\Component\Validator\Constraints\Length;
|
||||||
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
|
use Symfony\Component\Validator\Constraints\NotNull;
|
||||||
|
use Symfony\Component\Validator\Constraints\Range;
|
||||||
|
use Symfony\Component\Validator\Constraints\True;
|
||||||
use Symfony\Component\Validator\Constraints\Type;
|
use Symfony\Component\Validator\Constraints\Type;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author franek <franek@chicour.net>
|
* @author franek <franek@chicour.net>
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class ValidatorTypeGuesserTest extends \PHPUnit_Framework_TestCase
|
class ValidatorTypeGuesserTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
private $typeGuesser;
|
const TEST_CLASS = 'Symfony\Component\Form\Tests\Extension\Validator\ValidatorTypeGuesserTest_TestClass';
|
||||||
|
|
||||||
public function setUp()
|
const TEST_PROPERTY = 'property';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ValidatorTypeGuesser
|
||||||
|
*/
|
||||||
|
private $guesser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ClassMetadata
|
||||||
|
*/
|
||||||
|
private $metadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
private $metadataFactory;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
{
|
{
|
||||||
if (!class_exists('Symfony\Component\Validator\Constraint')) {
|
if (!class_exists('Symfony\Component\Validator\Constraint')) {
|
||||||
$this->markTestSkipped('The "Validator" component is not available');
|
$this->markTestSkipped('The "Validator" component is not available');
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
|
$this->metadata = new ClassMetadata(self::TEST_CLASS);
|
||||||
|
$this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
|
||||||
|
$this->metadataFactory->expects($this->any())
|
||||||
|
->method('getMetadataFor')
|
||||||
|
->with(self::TEST_CLASS)
|
||||||
|
->will($this->returnValue($this->metadata));
|
||||||
|
$this->guesser = new ValidatorTypeGuesser($this->metadataFactory);
|
||||||
|
}
|
||||||
|
|
||||||
$this->typeGuesser = new ValidatorTypeGuesser($metadataFactory);
|
public function guessRequiredProvider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(new NotNull(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
|
||||||
|
array(new NotBlank(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
|
||||||
|
array(new True(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
|
||||||
|
array(new Length(10), new ValueGuess(false, Guess::LOW_CONFIDENCE)),
|
||||||
|
array(new Range(array('min' => 1, 'max' => 20)), new ValueGuess(false, Guess::LOW_CONFIDENCE)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider guessRequiredProvider
|
||||||
|
*/
|
||||||
|
public function testGuessRequired($constraint, $guess)
|
||||||
|
{
|
||||||
|
// add distracting constraint
|
||||||
|
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY, new Email());
|
||||||
|
|
||||||
|
// add constraint under test
|
||||||
|
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY, $constraint);
|
||||||
|
|
||||||
|
$this->assertEquals($guess, $this->guesser->guessRequired(self::TEST_CLASS, self::TEST_PROPERTY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessRequiredReturnsFalseForUnmappedProperties()
|
||||||
|
{
|
||||||
|
$this->assertEquals(new ValueGuess(false, Guess::LOW_CONFIDENCE), $this->guesser->guessRequired(self::TEST_CLASS, self::TEST_PROPERTY));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGuessMaxLengthForConstraintWithMaxValue()
|
public function testGuessMaxLengthForConstraintWithMaxValue()
|
||||||
{
|
{
|
||||||
$constraint = new Length(array('max' => '2'));
|
$constraint = new Length(array('max' => '2'));
|
||||||
|
|
||||||
$result = $this->typeGuesser->guessMaxLengthForConstraint($constraint);
|
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
|
||||||
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
|
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
|
||||||
$this->assertEquals(2, $result->getValue());
|
$this->assertEquals(2, $result->getValue());
|
||||||
$this->assertEquals(Guess::HIGH_CONFIDENCE, $result->getConfidence());
|
$this->assertEquals(Guess::HIGH_CONFIDENCE, $result->getConfidence());
|
||||||
@ -48,24 +107,11 @@ class ValidatorTypeGuesserTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$constraint = new Length(array('min' => '2'));
|
$constraint = new Length(array('min' => '2'));
|
||||||
|
|
||||||
$result = $this->typeGuesser->guessMaxLengthForConstraint($constraint);
|
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
|
||||||
$this->assertNull($result);
|
$this->assertNull($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function maxLengthTypeProvider()
|
||||||
* @dataProvider dataProviderTestGuessMaxLengthForConstraintWithType
|
|
||||||
*/
|
|
||||||
public function testGuessMaxLengthForConstraintWithType($type)
|
|
||||||
{
|
|
||||||
$constraint = new Type($type);
|
|
||||||
|
|
||||||
$result = $this->typeGuesser->guessMaxLengthForConstraint($constraint);
|
|
||||||
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
|
|
||||||
$this->assertEquals(null, $result->getValue());
|
|
||||||
$this->assertEquals(Guess::MEDIUM_CONFIDENCE, $result->getConfidence());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function dataProviderTestGuessMaxLengthForConstraintWithType()
|
|
||||||
{
|
{
|
||||||
return array (
|
return array (
|
||||||
array('double'),
|
array('double'),
|
||||||
@ -74,4 +120,22 @@ class ValidatorTypeGuesserTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('real'),
|
array('real'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider maxLengthTypeProvider
|
||||||
|
*/
|
||||||
|
public function testGuessMaxLengthForConstraintWithType($type)
|
||||||
|
{
|
||||||
|
$constraint = new Type($type);
|
||||||
|
|
||||||
|
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
|
||||||
|
$this->assertNull($result->getValue());
|
||||||
|
$this->assertEquals(Guess::MEDIUM_CONFIDENCE, $result->getConfidence());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ValidatorTypeGuesserTest_TestClass
|
||||||
|
{
|
||||||
|
private $property;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user