diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php index 9a7a1f8774538..468ebd1166a7b 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -79,6 +79,24 @@ public function guessType($class, $property) } } + /** + * {@inheritDoc} + */ + public function guessAttributes($class, $property) + { + $attributes = array(); + + if ($guess = $this->guessMaxLength($class, $property)) { + $attributes['maxlength'] = $guess; + } + + if ($guess = $this->guessPattern($class, $property)) { + $attributes['pattern'] = $guess; + } + + return $attributes; + } + /** * {@inheritDoc} */ diff --git a/src/Symfony/Bridge/Propel1/Form/PropelTypeGuesser.php b/src/Symfony/Bridge/Propel1/Form/PropelTypeGuesser.php index 35382d89c3d2c..7632159182e6a 100644 --- a/src/Symfony/Bridge/Propel1/Form/PropelTypeGuesser.php +++ b/src/Symfony/Bridge/Propel1/Form/PropelTypeGuesser.php @@ -107,6 +107,24 @@ public function guessType($class, $property) } } + /** + * {@inheritDoc} + */ + public function guessAttributes($class, $property) + { + $attributes = array(); + + if ($guess = $this->guessMaxLength($class, $property)) { + $attributes['maxlength'] = $guess; + } + + if ($guess = $this->guessPattern($class, $property)) { + $attributes['pattern'] = $guess; + } + + return $attributes; + } + /** * {@inheritDoc} */ diff --git a/src/Symfony/Bridge/Propel1/Tests/Form/PropelTypeGuesserTest.php b/src/Symfony/Bridge/Propel1/Tests/Form/PropelTypeGuesserTest.php index bb59503e61c63..9804e4534948f 100644 --- a/src/Symfony/Bridge/Propel1/Tests/Form/PropelTypeGuesserTest.php +++ b/src/Symfony/Bridge/Propel1/Tests/Form/PropelTypeGuesserTest.php @@ -30,33 +30,34 @@ public function setUp() public function testGuessMaxLengthWithText() { - $value = $this->guesser->guessMaxLength(self::CLASS_NAME, 'value'); + $attributes = $this->guesser->guessAttributes(self::CLASS_NAME, 'value'); - $this->assertNotNull($value); - $this->assertEquals(255, $value->getValue()); + $this->assertArrayHasKey('maxlength', $attributes); + $this->assertEquals(255, $attributes['maxlength']->getValue()); } public function testGuessMaxLengthWithFloat() { - $value = $this->guesser->guessMaxLength(self::CLASS_NAME, 'price'); + $attributes = $this->guesser->guessAttributes(self::CLASS_NAME, 'price'); - $this->assertNotNull($value); - $this->assertNull($value->getValue()); + $this->assertArrayHasKey('maxlength', $attributes); + $this->assertNull($attributes['maxlength']->getValue()); } public function testGuessMinLengthWithText() { - $value = $this->guesser->guessPattern(self::CLASS_NAME, 'value'); + $attributes = $this->guesser->guessAttributes(self::CLASS_NAME, 'price'); - $this->assertNull($value); + $this->assertArrayHasKey('maxlength', $attributes); + $this->assertNull($attributes['maxlength']->getValue()); } public function testGuessMinLengthWithFloat() { - $value = $this->guesser->guessPattern(self::CLASS_NAME, 'price'); + $attributes = $this->guesser->guessAttributes(self::CLASS_NAME, 'price'); - $this->assertNotNull($value); - $this->assertNull($value->getValue()); + $this->assertArrayHasKey('maxlength', $attributes); + $this->assertNull($attributes['maxlength']->getValue()); } public function testGuessRequired() diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index c210f9e7924ac..3e9c73ef8c26a 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -11,6 +11,7 @@ CHANGELOG * [BC BREAK] added two optional parameters to FormInterface::getErrors() and changed the method to return a Symfony\Component\Form\FormErrorIterator instance instead of an array + * added the guessing of "min" and "max" attributes 2.4.0 ----- diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index c66c7b3fb9058..5c12d7dfd8ad3 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -191,9 +191,9 @@ public function setDefaultOptions(OptionsResolverInterface $resolver) 'empty_data' => $emptyData, 'trim' => true, 'required' => true, - 'read_only' => false, 'max_length' => null, 'pattern' => null, + 'read_only' => false, 'property_path' => null, 'mapped' => true, 'by_reference' => true, diff --git a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php index 5cd02daa91bec..e43d02f5f5d49 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php +++ b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php @@ -17,6 +17,7 @@ use Symfony\Component\Form\Guess\ValueGuess; use Symfony\Component\Validator\MetadataFactoryInterface; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\Range; class ValidatorTypeGuesser implements FormTypeGuesserInterface { @@ -39,6 +40,32 @@ public function guessType($class, $property) }); } + /** + * {@inheritDoc} + */ + public function guessAttributes($class, $property) + { + $attributes = array(); + + if ($guess = $this->guessMaxLength($class, $property)) { + $attributes['maxlength'] = $guess; + } + + if ($guess = $this->guessMinValue($class, $property)) { + $attributes['min'] = $guess; + } + + if ($guess = $this->guessMaxValue($class, $property)) { + $attributes['max'] = $guess; + } + + if ($guess = $this->guessPattern($class, $property)) { + $attributes['pattern'] = $guess; + } + + return $attributes; + } + /** * {@inheritDoc} */ @@ -65,6 +92,40 @@ public function guessMaxLength($class, $property) }); } + /** + * Returns a guess about the field's maximum value + * + * @param string $class The fully qualified class name + * @param string $property The name of the property to guess for + * + * @return Guess\ValueGuess|null A guess for the field's maximum value + */ + public function guessMaxValue($class, $property) + { + $guesser = $this; + + return $this->guess($class, $property, function (Constraint $constraint) use ($guesser) { + return $guesser->guessMaxValueForConstraint($constraint); + }); + } + + /** + * Returns a guess about the field's minimum value + * + * @param string $class The fully qualified class name + * @param string $property The name of the property to guess for + * + * @return Guess\ValueGuess|null A guess for the field's minimum value + */ + public function guessMinValue($class, $property) + { + $guesser = $this; + + return $this->guess($class, $property, function (Constraint $constraint) use ($guesser) { + return $guesser->guessMinValueForConstraint($constraint); + }); + } + /** * {@inheritDoc} */ @@ -214,6 +275,38 @@ public function guessMaxLengthForConstraint(Constraint $constraint) return null; } + /** + * Guesses a field's maximum value based on the given constraint + * + * @param Constraint $constraint The constraint to guess for + * + * @return ValueGuess|null The guess for the maximum value + */ + public function guessMaxValueForConstraint(Constraint $constraint) + { + if ($constraint instanceof Range && is_numeric($constraint->max)) { + return new ValueGuess($constraint->max, Guess::HIGH_CONFIDENCE); + } + + return null; + } + + /** + * Guesses a field's minimum value based on the given constraint + * + * @param Constraint $constraint The constraint to guess for + * + * @return ValueGuess|null The guess for the minimum value + */ + public function guessMinValueForConstraint(Constraint $constraint) + { + if ($constraint instanceof Range && is_numeric($constraint->min)) { + return new ValueGuess($constraint->min, Guess::HIGH_CONFIDENCE); + } + + return null; + } + /** * Guesses a field's pattern based on the given constraint * diff --git a/src/Symfony/Component/Form/FormFactory.php b/src/Symfony/Component/Form/FormFactory.php index 63b2fe442c1f8..55fd1bb0df3ea 100644 --- a/src/Symfony/Component/Form/FormFactory.php +++ b/src/Symfony/Component/Form/FormFactory.php @@ -25,6 +25,25 @@ class FormFactory implements FormFactoryInterface */ private $resolvedTypeFactory; + protected $supportedAttributes = array( + // rendered as input[type=text] + 'text' => array('maxlength', 'pattern'), + 'email' => array('maxlength', 'pattern'), + 'money' => array('maxlength', 'pattern'), + 'number' => array('maxlength', 'pattern'), + 'percent' => array('maxlength', 'pattern'), + // rendered as input[type=number] + 'integer' => array('max', 'min'), + // rendered as input[type=password] + 'password' => array('maxlength', 'pattern'), + // rendered as input[type=search] + 'search' => array('maxlength', 'pattern'), + // rendered as input[type=url] + 'url' => array('maxlength', 'pattern'), + // rendered as textarea + 'textarea' => array('maxlength'), + ); + public function __construct(FormRegistryInterface $registry, ResolvedFormTypeFactoryInterface $resolvedTypeFactory) { $this->registry = $registry; @@ -103,24 +122,11 @@ public function createBuilderForProperty($class, $property, $data = null, array } $typeGuess = $guesser->guessType($class, $property); - $maxLengthGuess = $guesser->guessMaxLength($class, $property); - $requiredGuess = $guesser->guessRequired($class, $property); - $patternGuess = $guesser->guessPattern($class, $property); + $guessedAttributes = $guesser->guessAttributes($class, $property); $type = $typeGuess ? $typeGuess->getType() : 'text'; - $maxLength = $maxLengthGuess ? $maxLengthGuess->getValue() : null; - $pattern = $patternGuess ? $patternGuess->getValue() : null; - - if (null !== $pattern) { - $options = array_merge(array('attr' => array('pattern' => $pattern)), $options); - } - - if (null !== $maxLength) { - $options = array_merge(array('attr' => array('maxlength' => $maxLength)), $options); - } - - if ($requiredGuess) { + if ($requiredGuess = $guesser->guessRequired($class, $property)) { $options = array_merge(array('required' => $requiredGuess->getValue()), $options); } @@ -129,6 +135,20 @@ public function createBuilderForProperty($class, $property, $data = null, array $options = array_merge($typeGuess->getOptions(), $options); } + $filteredAttributes = array(); + + foreach ($guessedAttributes as $key => $value) { + if (null !== $value->getValue() && isset($this->supportedAttributes[$type]) && in_array($key, $this->supportedAttributes[$type])) { + $filteredAttributes[$key] = $value->getValue(); + } + } + + if (!empty($filteredAttributes)) { + $options = array_merge(array( + 'attr' => $filteredAttributes + ), $options); + } + return $this->createNamedBuilder($property, $type, $data, $options); } diff --git a/src/Symfony/Component/Form/FormFactoryInterface.php b/src/Symfony/Component/Form/FormFactoryInterface.php index 31c46b55d7d29..46abd998757e0 100644 --- a/src/Symfony/Component/Form/FormFactoryInterface.php +++ b/src/Symfony/Component/Form/FormFactoryInterface.php @@ -93,7 +93,7 @@ public function createNamedBuilder($name, $type = 'form', $data = null, array $o /** * Returns a form builder for a property of a class. * - * If any of the 'max_length', 'required' and type options can be guessed, + * If any of the 'required' and type options can be guessed, * and are not provided in the options argument, the guessed value is used. * * @param string $class The fully qualified class name diff --git a/src/Symfony/Component/Form/FormTypeGuesserChain.php b/src/Symfony/Component/Form/FormTypeGuesserChain.php index 6e858ddffef39..0b29c58a7cd2e 100644 --- a/src/Symfony/Component/Form/FormTypeGuesserChain.php +++ b/src/Symfony/Component/Form/FormTypeGuesserChain.php @@ -80,6 +80,33 @@ public function guessPattern($class, $property) }); } + /** + * {@inheritDoc} + */ + public function guessAttributes($class, $property) + { + $attributes = array(); + + // Cleanup attributes if I get the same attribute from different guessers. + foreach ($this->guessers as $guesser) { + $guessedAttributes = $guesser->guessAttributes($class, $property); + + if (!is_array($guessedAttributes)) { + continue; + } + + foreach ($guessedAttributes as $key => $value) { + if (isset($attributes[$key])) { + $attributes[$key] = Guess::getBestGuess(array($attributes[$key], $value)); + } else { + $attributes[$key] = $value; + } + } + } + + return $attributes; + } + /** * Executes a closure for each guesser and returns the best guess from the * return values diff --git a/src/Symfony/Component/Form/FormTypeGuesserInterface.php b/src/Symfony/Component/Form/FormTypeGuesserInterface.php index 7cd384a798129..2550d8017005d 100644 --- a/src/Symfony/Component/Form/FormTypeGuesserInterface.php +++ b/src/Symfony/Component/Form/FormTypeGuesserInterface.php @@ -43,6 +43,8 @@ public function guessRequired($class, $property); * @param string $property The name of the property to guess for * * @return Guess\ValueGuess|null A guess for the field's maximum length + * + * @deprecated since 2.5, to be removed in 3.0. Use guessAttributes() instead. */ public function guessMaxLength($class, $property); @@ -59,6 +61,19 @@ public function guessMaxLength($class, $property); * @param string $property The name of the property to guess for * * @return Guess\ValueGuess|null A guess for the field's required pattern + * + * @deprecated since 2.5, to be removed in 3.0. Use guessAttributes() instead. */ public function guessPattern($class, $property); + + /** + * Returns an array of guessed attributes + * + * @param string $class The fully qualified class name + * @param string $property The name of the property to guess for + * @param ResolvedFormTypeInterface $type Field's type + * + * @return Guess\ValueGuess[] An array of guesses for the field's attributes + */ + public function guessAttributes($class, $property); } diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index 532dc41be75f5..eca512c6b242b 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -1334,6 +1334,21 @@ public function testInteger() ); } + public function testIntegerWithMinAndMax() + { + $form = $this->factory->createNamed('name', 'integer', 123, array('attr' => array('min' => -276, 'max' => 100))); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/input + [@type="number"] + [@name="name"] + [@value="123"] + [@min="-276"] + [@max="100"] +' + ); + } + public function testLanguage() { $form = $this->factory->createNamed('name', 'language', 'de'); @@ -1906,7 +1921,7 @@ public function testWidgetAttributes() $html = $this->renderWidget($form->createView()); // compare plain HTML to check the whitespace - $this->assertSame('', $html); + $this->assertSame('', $html); } public function testWidgetAttributeNameRepeatedIfTrue() diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php index 77be4b01e69c7..a2b94628bada4 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php @@ -31,7 +31,7 @@ public function testSetDataAdjustsSize() $form = $this->factory->create('collection', null, array( 'type' => 'text', 'options' => array( - 'attr' => array('maxlength' => 20), + 'attr' => array('maxlength' => 20) ), )); $form->setData(array('foo@foo.com', 'foo@bar.com')); @@ -41,18 +41,21 @@ public function testSetDataAdjustsSize() $this->assertCount(2, $form); $this->assertEquals('foo@foo.com', $form[0]->getData()); $this->assertEquals('foo@bar.com', $form[1]->getData()); - $formAttrs0 = $form[0]->getConfig()->getOption('attr'); - $formAttrs1 = $form[1]->getConfig()->getOption('attr'); - $this->assertEquals(20, $formAttrs0['maxlength']); - $this->assertEquals(20, $formAttrs1['maxlength']); + + $attrsForm0 = $form[0]->getConfig()->getOption('attr'); + $attrsForm1 = $form[1]->getConfig()->getOption('attr'); + + $this->assertEquals(20, $attrsForm0['maxlength']); + $this->assertEquals(20, $attrsForm1['maxlength']); $form->setData(array('foo@baz.com')); $this->assertInstanceOf('Symfony\Component\Form\Form', $form[0]); $this->assertFalse(isset($form[1])); $this->assertCount(1, $form); $this->assertEquals('foo@baz.com', $form[0]->getData()); - $formAttrs0 = $form[0]->getConfig()->getOption('attr'); - $this->assertEquals(20, $formAttrs0['maxlength']); + + $attrsForm0 = $form[0]->getConfig()->getOption('attr'); + $this->assertEquals(20, $attrsForm0['maxlength']); } public function testThrowsExceptionIfObjectIsNotTraversable() diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php index f42003d214c40..b0e628fc63af7 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php @@ -12,9 +12,8 @@ namespace Symfony\Component\Form\Tests\Extension\Validator; use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser; -use Symfony\Component\Form\Guess\Guess; use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\Type; +use Symfony\Component\Validator\Constraints\Range; /** * @author franek @@ -29,49 +28,95 @@ public function setUp() $this->markTestSkipped('The "Validator" component is not available'); } - $metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface'); + $this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface'); - $this->typeGuesser = new ValidatorTypeGuesser($metadataFactory); + $this->typeGuesser = new ValidatorTypeGuesser($this->metadataFactory); } - public function testGuessMaxLengthForConstraintWithMaxValue() + public function testGuessOptionsForConstraintWithMaxLength() { - $constraint = new Length(array('max' => '2')); + $class = new \stdClass(); - $result = $this->typeGuesser->guessMaxLengthForConstraint($constraint); - $this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result); - $this->assertEquals(2, $result->getValue()); - $this->assertEquals(Guess::HIGH_CONFIDENCE, $result->getConfidence()); + $this->setupMetadata($class, 'foo', array(new Length(array('max' => '2')))); + + $result = $this->typeGuesser->guessAttributes($class, 'foo'); + + $this->assertArrayHasKey('maxlength', $result); + $this->assertEquals(2, $result['maxlength']->getValue()); + $this->assertFalse(isset($result['min'])); } - public function testGuessMaxLengthForConstraintWithMinValue() + public function testGuessOptionsForConstraintWithMinLength() { - $constraint = new Length(array('min' => '2')); + $class = new \stdClass(); + + $this->setupMetadata($class, 'foo', array(new Length(array('min' => '2')))); - $result = $this->typeGuesser->guessMaxLengthForConstraint($constraint); - $this->assertNull($result); + $result = $this->typeGuesser->guessAttributes($class, 'foo'); + + $this->assertFalse(isset($result['maxlength'])); } - /** -* @dataProvider dataProviderTestGuessMaxLengthForConstraintWithType -*/ - public function testGuessMaxLengthForConstraintWithType($type) + public function testGuessOptionsForConstraintWithMinValue() { - $constraint = new Type($type); + $class = new \stdClass(); + + $this->setupMetadata($class, 'foo', array(new Range(array('min' => '2')))); - $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()); + $result = $this->typeGuesser->guessAttributes($class, 'foo'); + + $this->assertArrayHasKey('min', $result); + $this->assertEquals(2, $result['min']->getValue()); } - public static function dataProviderTestGuessMaxLengthForConstraintWithType() + public function testGuessOptionsForConstraintWithMaxValue() { - return array ( - array('double'), - array('float'), - array('numeric'), - array('real') - ); + $class = new \stdClass(); + + $this->setupMetadata($class, 'foo', array(new Range(array('max' => '2')))); + + $result = $this->typeGuesser->guessAttributes($class, 'foo'); + + $this->assertArrayHasKey('max', $result); + $this->assertEquals(2, $result['max']->getValue()); + } + + public function testGuessOptionsForConstraintWithMinAndMaxValue() + { + $class = new \stdClass(); + + $this->setupMetadata($class, 'foo', array(new Range(array('min' => 1, 'max' => '2')))); + + $result = $this->typeGuesser->guessAttributes($class, 'foo'); + + $this->assertArrayHasKey('min', $result); + $this->assertEquals(1, $result['min']->getValue()); + $this->assertArrayHasKey('max', $result); + $this->assertEquals(2, $result['max']->getValue()); + } + + private function setupMetadata($class, $property, array $constraints) + { + $this->elementMetadata = $this->getMock('Symfony\Component\Validator\Mapping\ElementMetadata'); + $this->elementMetadata->expects($this->any()) + ->method('getConstraints') + ->will($this->returnValue($constraints)); + + $this->metadata = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata') + ->disableOriginalConstructor() + ->getMock(); + $this->metadata->expects($this->any()) + ->method('hasMemberMetadatas') + ->with($property) + ->will($this->returnValue(true)); + $this->metadata->expects($this->any()) + ->method('getMemberMetadatas') + ->with($property) + ->will($this->returnValue(array($this->elementMetadata))); + + $this->metadataFactory->expects($this->any()) + ->method('getMetadataFor') + ->with($class) + ->will($this->returnValue($this->metadata)); } } diff --git a/src/Symfony/Component/Form/Tests/FormFactoryTest.php b/src/Symfony/Component/Form/Tests/FormFactoryTest.php index a06b49876e1ca..744f5e0d1627c 100644 --- a/src/Symfony/Component/Form/Tests/FormFactoryTest.php +++ b/src/Symfony/Component/Form/Tests/FormFactoryTest.php @@ -446,13 +446,13 @@ public function testCreateBuilderCreatesTextFormIfNoGuess() public function testOptionsCanBeOverridden() { $this->guesser1->expects($this->once()) - ->method('guessType') - ->with('Application\Author', 'firstName') - ->will($this->returnValue(new TypeGuess( - 'text', - array('attr' => array('maxlength' => 10)), - Guess::MEDIUM_CONFIDENCE - ))); + ->method('guessType') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(new TypeGuess( + 'text', + array('attr' => array('maxlength' => 10)), + Guess::MEDIUM_CONFIDENCE + ))); $factory = $this->getMockFactory(array('createNamedBuilder')); @@ -474,20 +474,20 @@ public function testOptionsCanBeOverridden() public function testCreateBuilderUsesMaxLengthIfFound() { $this->guesser1->expects($this->once()) - ->method('guessMaxLength') - ->with('Application\Author', 'firstName') - ->will($this->returnValue(new ValueGuess( - 15, - Guess::MEDIUM_CONFIDENCE - ))); + ->method('guessAttributes') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(array('maxlength' => new ValueGuess( + 15, + Guess::MEDIUM_CONFIDENCE + )))); $this->guesser2->expects($this->once()) - ->method('guessMaxLength') - ->with('Application\Author', 'firstName') - ->will($this->returnValue(new ValueGuess( - 20, - Guess::HIGH_CONFIDENCE - ))); + ->method('guessAttributes') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(array('maxlength' => new ValueGuess( + 20, + Guess::HIGH_CONFIDENCE + )))); $factory = $this->getMockFactory(array('createNamedBuilder')); @@ -504,23 +504,126 @@ public function testCreateBuilderUsesMaxLengthIfFound() $this->assertEquals('builderInstance', $this->builder); } + public function testCreateBuilderUsesMinAndMaxValueIfFound() + { + $this->guesser1->expects($this->once()) + ->method('guessType') + ->will($this->returnValue(new TypeGuess( + 'integer', + array(), + Guess::HIGH_CONFIDENCE + ))); + + $this->guesser1->expects($this->once()) + ->method('guessAttributes') + ->with('Application\Temperature', 'degrees') + ->will($this->returnValue(array('min' => new ValueGuess( + -276, + Guess::HIGH_CONFIDENCE + )))); + + $this->guesser2->expects($this->once()) + ->method('guessAttributes') + ->with('Application\Temperature', 'degrees') + ->will($this->returnValue(array('max' => new ValueGuess( + 100, + Guess::HIGH_CONFIDENCE + )))); + + $factory = $this->getMockFactory(array('createNamedBuilder')); + + $factory->expects($this->once()) + ->method('createNamedBuilder') + ->with('degrees', 'integer', null, array('attr' => array('min' => -276, 'max' => 100))) + ->will($this->returnValue('builderInstance')); + + $this->builder = $factory->createBuilderForProperty( + 'Application\Temperature', + 'degrees' + ); + + $this->assertEquals('builderInstance', $this->builder); + } + + public function testMinAndMaxAttributesCanBeOverridden() + { + $this->guesser1->expects($this->once()) + ->method('guessType') + ->will($this->returnValue(new TypeGuess( + 'integer', + array(), + Guess::HIGH_CONFIDENCE + ))); + + $this->guesser1->expects($this->once()) + ->method('guessAttributes') + ->with('Application\Temperature', 'degrees') + ->will($this->returnValue(array('min' => new ValueGuess( + -276, + Guess::HIGH_CONFIDENCE + )))); + + $factory = $this->getMockFactory(array('createNamedBuilder')); + + $factory->expects($this->once()) + ->method('createNamedBuilder') + ->with('degrees', 'integer', null, array('attr' => array('min' => 50))) + ->will($this->returnValue('builderInstance')); + + $this->builder = $factory->createBuilderForProperty( + 'Application\Temperature', + 'degrees', + null, + array('attr' => array('min' => 50)) + ); + + $this->assertEquals('builderInstance', $this->builder); + } + + public function testMinAndMaxAttributesAreNotAddedToTextType() + { + $this->guesser1->expects($this->once()) + ->method('guessAttributes') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(array('min' => new ValueGuess( + -276, + Guess::HIGH_CONFIDENCE + )))); + + $factory = $this->getMockFactory(array('createNamedBuilder')); + + $factory->expects($this->once()) + ->method('createNamedBuilder') + ->with('firstName', 'text', null) + ->will($this->returnValue('builderInstance')); + + $this->builder = $factory->createBuilderForProperty( + 'Application\Author', + 'firstName', + null, + array('attr' => array('min' => 50)) + ); + + $this->assertEquals('builderInstance', $this->builder); + } + public function testCreateBuilderUsesRequiredSettingWithHighestConfidence() { $this->guesser1->expects($this->once()) - ->method('guessRequired') - ->with('Application\Author', 'firstName') - ->will($this->returnValue(new ValueGuess( - true, - Guess::MEDIUM_CONFIDENCE - ))); + ->method('guessRequired') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(new ValueGuess( + true, + Guess::MEDIUM_CONFIDENCE + ))); $this->guesser2->expects($this->once()) - ->method('guessRequired') - ->with('Application\Author', 'firstName') - ->will($this->returnValue(new ValueGuess( - false, - Guess::HIGH_CONFIDENCE - ))); + ->method('guessRequired') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(new ValueGuess( + false, + Guess::HIGH_CONFIDENCE + ))); $factory = $this->getMockFactory(array('createNamedBuilder')); @@ -540,20 +643,20 @@ public function testCreateBuilderUsesRequiredSettingWithHighestConfidence() public function testCreateBuilderUsesPatternIfFound() { $this->guesser1->expects($this->once()) - ->method('guessPattern') - ->with('Application\Author', 'firstName') - ->will($this->returnValue(new ValueGuess( - '[a-z]', - Guess::MEDIUM_CONFIDENCE - ))); + ->method('guessAttributes') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(array('pattern' => new ValueGuess( + '[a-z]', + Guess::MEDIUM_CONFIDENCE + )))); $this->guesser2->expects($this->once()) - ->method('guessPattern') - ->with('Application\Author', 'firstName') - ->will($this->returnValue(new ValueGuess( - '[a-zA-Z]', - Guess::HIGH_CONFIDENCE - ))); + ->method('guessAttributes') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(array('pattern' => new ValueGuess( + '[a-zA-Z]', + Guess::HIGH_CONFIDENCE + )))); $factory = $this->getMockFactory(array('createNamedBuilder')); @@ -570,6 +673,31 @@ public function testCreateBuilderUsesPatternIfFound() $this->assertEquals('builderInstance', $this->builder); } + public function testCreateBuilderWithNullAttribute() + { + $this->guesser1->expects($this->once()) + ->method('guessAttributes') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(array('maxlength' => new ValueGuess( + null, + Guess::MEDIUM_CONFIDENCE + )))); + + $factory = $this->getMockFactory(array('createNamedBuilder')); + + $factory->expects($this->once()) + ->method('createNamedBuilder') + ->with('firstName', 'text', null, array()) + ->will($this->returnValue('builderInstance')); + + $this->builder = $factory->createBuilderForProperty( + 'Application\Author', + 'firstName' + ); + + $this->assertEquals('builderInstance', $this->builder); + } + private function getMockFactory(array $methods = array()) { return $this->getMockBuilder('Symfony\Component\Form\FormFactory') pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy