From 4f5b44bd3bd490309eb2ba7b44df4769816ba729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Sat, 3 Aug 2013 19:26:54 +0200 Subject: twig implementation --- .../Form/Tests/AbstractTableLayoutTest.php | 509 +++++++++++++++++++++ 1 file changed, 509 insertions(+) create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php (limited to 'vendor/symfony/form/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php') diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php new file mode 100644 index 00000000..5c911951 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php @@ -0,0 +1,509 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests; + +use Symfony\Component\Form\FormError; + +abstract class AbstractTableLayoutTest extends AbstractLayoutTest +{ + public function testRow() + { + $form = $this->factory->createNamed('name', 'text'); + $form->addError(new FormError('[trans]Error![/trans]')); + $view = $form->createView(); + $html = $this->renderRow($view); + + $this->assertMatchesXpath($html, +'/tr + [ + ./td + [./label[@for="name"]] + /following-sibling::td + [ + ./ul + [./li[.="[trans]Error![/trans]"]] + [count(./li)=1] + /following-sibling::input[@id="name"] + ] + ] +' + ); + } + + public function testLabelIsNotRenderedWhenSetToFalse() + { + $form = $this->factory->createNamed('name', 'text', null, array( + 'label' => false + )); + $html = $this->renderRow($form->createView()); + + $this->assertMatchesXpath($html, +'/tr + [ + ./td + [count(//label)=0] + /following-sibling::td + [./input[@id="name"]] + ] +' + ); + } + + public function testRepeatedRow() + { + $form = $this->factory->createNamed('name', 'repeated'); + $html = $this->renderRow($form->createView()); + + $this->assertMatchesXpath($html, +'/tr + [ + ./td + [./label[@for="name_first"]] + /following-sibling::td + [./input[@id="name_first"]] + ] +/following-sibling::tr + [ + ./td + [./label[@for="name_second"]] + /following-sibling::td + [./input[@id="name_second"]] + ] +/following-sibling::tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] + [count(../tr)=3] +' + ); + } + + public function testRepeatedRowWithErrors() + { + $form = $this->factory->createNamed('name', 'repeated'); + $form->addError(new FormError('[trans]Error![/trans]')); + $view = $form->createView(); + $html = $this->renderRow($view); + + // The errors of the form are not rendered by intention! + // In practice, repeated fields cannot have errors as all errors + // on them are mapped to the first child. + // (see RepeatedTypeValidatorExtension) + + $this->assertMatchesXpath($html, +'/tr + [ + ./td + [./label[@for="name_first"]] + /following-sibling::td + [./input[@id="name_first"]] + ] +/following-sibling::tr + [ + ./td + [./label[@for="name_second"]] + /following-sibling::td + [./input[@id="name_second"]] + ] +/following-sibling::tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] + [count(../tr)=3] +' + ); + } + + public function testButtonRow() + { + $form = $this->factory->createNamed('name', 'button'); + $view = $form->createView(); + $html = $this->renderRow($view); + + $this->assertMatchesXpath($html, +'/tr + [ + ./td + [.=""] + /following-sibling::td + [./button[@type="button"][@name="name"]] + ] + [count(//label)=0] +' + ); + } + + public function testRest() + { + $view = $this->factory->createNamedBuilder('name', 'form') + ->add('field1', 'text') + ->add('field2', 'repeated') + ->add('field3', 'text') + ->add('field4', 'text') + ->getForm() + ->createView(); + + // Render field2 row -> does not implicitly call renderWidget because + // it is a repeated field! + $this->renderRow($view['field2']); + + // Render field3 widget + $this->renderWidget($view['field3']); + + // Rest should only contain field1 and field4 + $html = $this->renderRest($view); + + $this->assertMatchesXpath($html, +'/tr + [ + ./td + [./label[@for="name_field1"]] + /following-sibling::td + [./input[@id="name_field1"]] + ] +/following-sibling::tr + [ + ./td + [./label[@for="name_field4"]] + /following-sibling::td + [./input[@id="name_field4"]] + ] + [count(../tr)=3] + [count(..//label)=2] + [count(..//input)=3] +/following-sibling::tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] +' + ); + } + + public function testCollection() + { + $form = $this->factory->createNamed('name', 'collection', array('a', 'b'), array( + 'type' => 'text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/table + [ + ./tr[./td/input[@type="text"][@value="a"]] + /following-sibling::tr[./td/input[@type="text"][@value="b"]] + /following-sibling::tr[@style="display: none"][./td[@colspan="2"]/input[@type="hidden"][@id="name__token"]] + ] + [count(./tr[./td/input])=3] +' + ); + } + + public function testEmptyCollection() + { + $form = $this->factory->createNamed('name', 'collection', array(), array( + 'type' => 'text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/table + [./tr[@style="display: none"][./td[@colspan="2"]/input[@type="hidden"][@id="name__token"]]] + [count(./tr[./td/input])=1] +' + ); + } + + public function testForm() + { + $view = $this->factory->createNamedBuilder('name', 'form') + ->setMethod('PUT') + ->setAction('http://example.com') + ->add('firstName', 'text') + ->add('lastName', 'text') + ->getForm() + ->createView(); + + $html = $this->renderForm($view, array( + 'id' => 'my&id', + 'attr' => array('class' => 'my&class'), + )); + + $this->assertMatchesXpath($html, +'/form + [ + ./input[@type="hidden"][@name="_method"][@value="PUT"] + /following-sibling::table + [ + ./tr + [ + ./td + [./label[@for="name_firstName"]] + /following-sibling::td + [./input[@id="name_firstName"]] + ] + /following-sibling::tr + [ + ./td + [./label[@for="name_lastName"]] + /following-sibling::td + [./input[@id="name_lastName"]] + ] + /following-sibling::tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] + ] + [count(.//input)=3] + [@id="my&id"] + [@class="my&class"] + ] + [@method="post"] + [@action="http://example.com"] + [@class="my&class"] +' + ); + } + + public function testFormWidget() + { + $view = $this->factory->createNamedBuilder('name', 'form') + ->add('firstName', 'text') + ->add('lastName', 'text') + ->getForm() + ->createView(); + + $this->assertWidgetMatchesXpath($view, array(), +'/table + [ + ./tr + [ + ./td + [./label[@for="name_firstName"]] + /following-sibling::td + [./input[@id="name_firstName"]] + ] + /following-sibling::tr + [ + ./td + [./label[@for="name_lastName"]] + /following-sibling::td + [./input[@id="name_lastName"]] + ] + /following-sibling::tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] + ] + [count(.//input)=3] +' + ); + } + + // https://github.com/symfony/symfony/issues/2308 + public function testNestedFormError() + { + $form = $this->factory->createNamedBuilder('name', 'form') + ->add($this->factory + ->createNamedBuilder('child', 'form', null, array('error_bubbling' => false)) + ->add('grandChild', 'form') + ) + ->getForm(); + + $form->get('child')->addError(new FormError('[trans]Error![/trans]')); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/table + [ + ./tr/td/ul[./li[.="[trans]Error![/trans]"]] + /following-sibling::table[@id="name_child"] + ] + [count(.//li[.="[trans]Error![/trans]"])=1] +' + ); + } + + public function testCsrf() + { + $this->csrfProvider->expects($this->any()) + ->method('generateCsrfToken') + ->will($this->returnValue('foo&bar')); + + $form = $this->factory->createNamedBuilder('name', 'form') + ->add($this->factory + // No CSRF protection on nested forms + ->createNamedBuilder('child', 'form') + ->add($this->factory->createNamedBuilder('grandchild', 'text')) + ) + ->getForm(); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/table + [ + ./tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] + ] + [count(.//input[@type="hidden"])=1] +' + ); + } + + public function testRepeated() + { + $form = $this->factory->createNamed('name', 'repeated', 'foobar', array( + 'type' => 'text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/table + [ + ./tr + [ + ./td + [./label[@for="name_first"]] + /following-sibling::td + [./input[@type="text"][@id="name_first"]] + ] + /following-sibling::tr + [ + ./td + [./label[@for="name_second"]] + /following-sibling::td + [./input[@type="text"][@id="name_second"]] + ] + /following-sibling::tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] + ] + [count(.//input)=3] +' + ); + } + + public function testRepeatedWithCustomOptions() + { + $form = $this->factory->createNamed('name', 'repeated', 'foobar', array( + 'type' => 'password', + 'first_options' => array('label' => 'Test', 'required' => false), + 'second_options' => array('label' => 'Test2') + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/table + [ + ./tr + [ + ./td + [./label[@for="name_first"][.="[trans]Test[/trans]"]] + /following-sibling::td + [./input[@type="password"][@id="name_first"][@required="required"]] + ] + /following-sibling::tr + [ + ./td + [./label[@for="name_second"][.="[trans]Test2[/trans]"]] + /following-sibling::td + [./input[@type="password"][@id="name_second"][@required="required"]] + ] + /following-sibling::tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] + ] + [count(.//input)=3] +' + ); + } + + /** + * The block "_name_child_label" should be overridden in the theme of the + * implemented driver. + */ + public function testCollectionRowWithCustomBlock() + { + $collection = array('one', 'two', 'three'); + $form = $this->factory->createNamedBuilder('name', 'collection', $collection) + ->getForm(); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/table + [ + ./tr[./td/label[.="Custom label: [trans]0[/trans]"]] + /following-sibling::tr[./td/label[.="Custom label: [trans]1[/trans]"]] + /following-sibling::tr[./td/label[.="Custom label: [trans]2[/trans]"]] + ] +' + ); + } + + public function testFormEndWithRest() + { + $view = $this->factory->createNamedBuilder('name', 'form') + ->add('field1', 'text') + ->add('field2', 'text') + ->getForm() + ->createView(); + + $this->renderWidget($view['field1']); + + // Rest should only contain field2 + $html = $this->renderEnd($view); + + // Insert the start tag, the end tag should be rendered by the helper + // Unfortunately this is not valid HTML, because the surrounding table + // tag is missing. If someone renders a form with table layout + // manually, she should call form_rest() explicitly within the + // tag. + $this->assertMatchesXpath('' . $html, +'/form + [ + ./tr + [ + ./td + [./label[@for="name_field2"]] + /following-sibling::td + [./input[@id="name_field2"]] + ] + /following-sibling::tr[@style="display: none"] + [./td[@colspan="2"]/input + [@type="hidden"] + [@id="name__token"] + ] + ] +' + ); + } + + public function testFormEndWithoutRest() + { + $view = $this->factory->createNamedBuilder('name', 'form') + ->add('field1', 'text') + ->add('field2', 'text') + ->getForm() + ->createView(); + + $this->renderWidget($view['field1']); + + // Rest should only contain field2, but isn't rendered + $html = $this->renderEnd($view, array('render_rest' => false)); + + $this->assertEquals('', $html); + } +} -- cgit v1.2.3