"Fossies" - the Fresh Open Source Software Archive

Member "Symfony/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php" (30 Mar 2020, 81551 Bytes) of package /linux/www/Symfony_Standard_Vendors_3.4.39.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 <?php
    2 
    3 /*
    4  * This file is part of the Symfony package.
    5  *
    6  * (c) Fabien Potencier <fabien@symfony.com>
    7  *
    8  * For the full copyright and license information, please view the LICENSE
    9  * file that was distributed with this source code.
   10  */
   11 
   12 namespace Symfony\Bridge\Twig\Tests\Extension;
   13 
   14 use Symfony\Component\Form\FormError;
   15 use Symfony\Component\Form\Tests\AbstractLayoutTest;
   16 
   17 abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
   18 {
   19     protected static $supportedFeatureSetVersion = 304;
   20 
   21     public function testLabelOnForm()
   22     {
   23         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType');
   24         $view = $form->createView();
   25         $this->renderWidget($view, ['label' => 'foo']);
   26         $html = $this->renderLabel($view);
   27 
   28         $this->assertMatchesXpath($html,
   29 '/label
   30     [@class="control-label required"]
   31     [.="[trans]Name[/trans]"]
   32 '
   33         );
   34     }
   35 
   36     public function testLabelDoesNotRenderFieldAttributes()
   37     {
   38         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
   39         $html = $this->renderLabel($form->createView(), null, [
   40             'attr' => [
   41                 'class' => 'my&class',
   42             ],
   43         ]);
   44 
   45         $this->assertMatchesXpath($html,
   46 '/label
   47     [@for="name"]
   48     [@class="control-label required"]
   49 '
   50         );
   51     }
   52 
   53     public function testLabelWithCustomAttributesPassedDirectly()
   54     {
   55         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
   56         $html = $this->renderLabel($form->createView(), null, [
   57             'label_attr' => [
   58                 'class' => 'my&class',
   59             ],
   60         ]);
   61 
   62         $this->assertMatchesXpath($html,
   63 '/label
   64     [@for="name"]
   65     [@class="my&class control-label required"]
   66 '
   67         );
   68     }
   69 
   70     public function testLabelWithCustomTextAndCustomAttributesPassedDirectly()
   71     {
   72         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
   73         $html = $this->renderLabel($form->createView(), 'Custom label', [
   74             'label_attr' => [
   75                 'class' => 'my&class',
   76             ],
   77         ]);
   78 
   79         $this->assertMatchesXpath($html,
   80 '/label
   81     [@for="name"]
   82     [@class="my&class control-label required"]
   83     [.="[trans]Custom label[/trans]"]
   84 '
   85         );
   86     }
   87 
   88     public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly()
   89     {
   90         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', null, [
   91             'label' => 'Custom label',
   92         ]);
   93         $html = $this->renderLabel($form->createView(), null, [
   94             'label_attr' => [
   95                 'class' => 'my&class',
   96             ],
   97         ]);
   98 
   99         $this->assertMatchesXpath($html,
  100 '/label
  101     [@for="name"]
  102     [@class="my&class control-label required"]
  103     [.="[trans]Custom label[/trans]"]
  104 '
  105         );
  106     }
  107 
  108     public function testErrors()
  109     {
  110         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
  111         $form->addError(new FormError('[trans]Error 1[/trans]'));
  112         $form->addError(new FormError('[trans]Error 2[/trans]'));
  113         $view = $form->createView();
  114         $html = $this->renderErrors($view);
  115 
  116         $this->assertMatchesXpath($html,
  117 '/div
  118     [@class="alert alert-danger"]
  119     [
  120         ./ul
  121             [@class="list-unstyled"]
  122             [
  123                 ./li
  124                     [.=" [trans]Error 1[/trans]"]
  125                     [
  126                         ./span[@class="glyphicon glyphicon-exclamation-sign"]
  127                     ]
  128                 /following-sibling::li
  129                     [.=" [trans]Error 2[/trans]"]
  130                     [
  131                         ./span[@class="glyphicon glyphicon-exclamation-sign"]
  132                     ]
  133             ]
  134             [count(./li)=2]
  135     ]
  136 '
  137         );
  138     }
  139 
  140     public function testOverrideWidgetBlock()
  141     {
  142         // see custom_widgets.html.twig
  143         $form = $this->factory->createNamed('text_id', 'Symfony\Component\Form\Extension\Core\Type\TextType');
  144         $html = $this->renderWidget($form->createView());
  145 
  146         $this->assertMatchesXpath($html,
  147 '/div
  148     [
  149         ./input
  150         [@type="text"]
  151         [@id="text_id"]
  152         [@class="form-control"]
  153     ]
  154     [@id="container"]
  155 '
  156         );
  157     }
  158 
  159     public function testCheckedCheckbox()
  160     {
  161         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', true);
  162 
  163         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
  164 '/div
  165     [@class="checkbox"]
  166     [
  167         ./label
  168             [.=" [trans]Name[/trans]"]
  169             [
  170                 ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class"][@checked="checked"][@value="1"]
  171             ]
  172     ]
  173 '
  174         );
  175     }
  176 
  177     public function testUncheckedCheckbox()
  178     {
  179         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', false);
  180 
  181         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
  182 '/div
  183     [@class="checkbox"]
  184     [
  185         ./label
  186             [.=" [trans]Name[/trans]"]
  187             [
  188                 ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class"][not(@checked)]
  189             ]
  190     ]
  191 '
  192         );
  193     }
  194 
  195     public function testCheckboxWithValue()
  196     {
  197         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', false, [
  198             'value' => 'foo&bar',
  199         ]);
  200 
  201         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
  202 '/div
  203     [@class="checkbox"]
  204     [
  205         ./label
  206             [.=" [trans]Name[/trans]"]
  207             [
  208                 ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class"][@value="foo&bar"]
  209             ]
  210     ]
  211 '
  212         );
  213     }
  214 
  215     public function testSingleChoice()
  216     {
  217         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  218             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  219             'multiple' => false,
  220             'expanded' => false,
  221         ]);
  222 
  223         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  224 '/select
  225     [@name="name"]
  226     [@class="my&class form-control"]
  227     [not(@required)]
  228     [
  229         ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  230         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  231     ]
  232     [count(./option)=2]
  233 '
  234         );
  235     }
  236 
  237     public function testSingleChoiceAttributesWithMainAttributes()
  238     {
  239         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  240             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  241             'multiple' => false,
  242             'expanded' => false,
  243             'attr' => ['class' => 'bar&baz'],
  244         ]);
  245 
  246         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'bar&baz']],
  247 '/select
  248     [@name="name"]
  249     [@class="bar&baz form-control"]
  250     [not(@required)]
  251     [
  252         ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  253         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  254     ]
  255     [count(./option)=2]
  256 '
  257         );
  258     }
  259 
  260     public function testSingleExpandedChoiceAttributesWithMainAttributes()
  261     {
  262         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  263             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  264             'multiple' => false,
  265             'expanded' => true,
  266             'attr' => ['class' => 'bar&baz'],
  267         ]);
  268 
  269         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'bar&baz']],
  270 '/div
  271     [@class="bar&baz"]
  272     [
  273         ./div
  274             [@class="radio"]
  275             [
  276                 ./label
  277                     [.=" [trans]Choice&A[/trans]"]
  278                     [
  279                         ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
  280                     ]
  281             ]
  282         /following-sibling::div
  283             [@class="radio"]
  284             [
  285                 ./label
  286                     [.=" [trans]Choice&B[/trans]"]
  287                     [
  288                         ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
  289                     ]
  290             ]
  291         /following-sibling::input[@type="hidden"][@id="name__token"]
  292     ]
  293 '
  294         );
  295     }
  296 
  297     public function testSelectWithSizeBiggerThanOneCanBeRequired()
  298     {
  299         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', null, [
  300             'choices' => ['a', 'b'],
  301             'multiple' => false,
  302             'expanded' => false,
  303             'attr' => ['size' => 2],
  304         ]);
  305 
  306         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => '']],
  307 '/select
  308     [@name="name"]
  309     [@required="required"]
  310     [@size="2"]
  311     [count(./option)=2]
  312 '
  313         );
  314     }
  315 
  316     public function testSingleChoiceWithoutTranslation()
  317     {
  318         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  319             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  320             'multiple' => false,
  321             'expanded' => false,
  322             'choice_translation_domain' => false,
  323         ]);
  324 
  325         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  326 '/select
  327     [@name="name"]
  328     [@class="my&class form-control"]
  329     [not(@required)]
  330     [
  331         ./option[@value="&a"][@selected="selected"][.="Choice&A"]
  332         /following-sibling::option[@value="&b"][not(@selected)][.="Choice&B"]
  333     ]
  334     [count(./option)=2]
  335 '
  336         );
  337     }
  338 
  339     public function testSingleChoiceWithPlaceholderWithoutTranslation()
  340     {
  341         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  342             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  343             'multiple' => false,
  344             'expanded' => false,
  345             'required' => false,
  346             'translation_domain' => false,
  347             'placeholder' => 'Placeholder&Not&Translated',
  348         ]);
  349 
  350         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  351 '/select
  352     [@name="name"]
  353     [@class="my&class form-control"]
  354     [not(@required)]
  355     [
  356         ./option[@value=""][not(@selected)][not(@disabled)][.="Placeholder&Not&Translated"]
  357         /following-sibling::option[@value="&a"][@selected="selected"][.="Choice&A"]
  358         /following-sibling::option[@value="&b"][not(@selected)][.="Choice&B"]
  359     ]
  360     [count(./option)=3]
  361 '
  362         );
  363     }
  364 
  365     public function testSingleChoiceAttributes()
  366     {
  367         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  368             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  369             'choice_attr' => ['Choice&B' => ['class' => 'foo&bar']],
  370             'multiple' => false,
  371             'expanded' => false,
  372         ]);
  373 
  374         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  375 '/select
  376     [@name="name"]
  377     [@class="my&class form-control"]
  378     [not(@required)]
  379     [
  380         ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  381         /following-sibling::option[@value="&b"][@class="foo&bar"][not(@selected)][.="[trans]Choice&B[/trans]"]
  382     ]
  383     [count(./option)=2]
  384 '
  385         );
  386     }
  387 
  388     public function testSingleChoiceWithPreferred()
  389     {
  390         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  391             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  392             'preferred_choices' => ['&b'],
  393             'multiple' => false,
  394             'expanded' => false,
  395         ]);
  396 
  397         $this->assertWidgetMatchesXpath($form->createView(), ['separator' => '-- sep --', 'attr' => ['class' => 'my&class']],
  398 '/select
  399     [@name="name"]
  400     [@class="my&class form-control"]
  401     [not(@required)]
  402     [
  403         ./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  404         /following-sibling::option[@disabled="disabled"][not(@selected)][.="-- sep --"]
  405         /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  406     ]
  407 '
  408         );
  409     }
  410 
  411     public function testSingleChoiceWithPreferredAndNoSeparator()
  412     {
  413         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  414             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  415             'preferred_choices' => ['&b'],
  416             'multiple' => false,
  417             'expanded' => false,
  418         ]);
  419 
  420         $this->assertWidgetMatchesXpath($form->createView(), ['separator' => null, 'attr' => ['class' => 'my&class']],
  421 '/select
  422     [@name="name"]
  423     [@class="my&class form-control"]
  424     [not(@required)]
  425     [
  426         ./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  427         /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  428     ]
  429 '
  430         );
  431     }
  432 
  433     public function testSingleChoiceWithPreferredAndBlankSeparator()
  434     {
  435         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  436             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  437             'preferred_choices' => ['&b'],
  438             'multiple' => false,
  439             'expanded' => false,
  440         ]);
  441 
  442         $this->assertWidgetMatchesXpath($form->createView(), ['separator' => '', 'attr' => ['class' => 'my&class']],
  443 '/select
  444     [@name="name"]
  445     [@class="my&class form-control"]
  446     [not(@required)]
  447     [
  448         ./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  449         /following-sibling::option[@disabled="disabled"][not(@selected)][.=""]
  450         /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  451     ]
  452 '
  453         );
  454     }
  455 
  456     public function testChoiceWithOnlyPreferred()
  457     {
  458         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  459             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  460             'preferred_choices' => ['&a', '&b'],
  461             'multiple' => false,
  462             'expanded' => false,
  463         ]);
  464 
  465         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  466 '/select
  467     [@class="my&class form-control"]
  468 '
  469         );
  470     }
  471 
  472     public function testSingleChoiceNonRequired()
  473     {
  474         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  475             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  476             'required' => false,
  477             'multiple' => false,
  478             'expanded' => false,
  479         ]);
  480 
  481         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  482 '/select
  483     [@name="name"]
  484     [@class="my&class form-control"]
  485     [not(@required)]
  486     [
  487         ./option[@value=""][.=""]
  488         /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  489         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  490     ]
  491     [count(./option)=3]
  492 '
  493         );
  494     }
  495 
  496     public function testSingleChoiceNonRequiredNoneSelected()
  497     {
  498         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', null, [
  499             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  500             'required' => false,
  501             'multiple' => false,
  502             'expanded' => false,
  503         ]);
  504 
  505         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  506 '/select
  507     [@name="name"]
  508     [@class="my&class form-control"]
  509     [not(@required)]
  510     [
  511         ./option[@value=""][.=""]
  512         /following-sibling::option[@value="&a"][not(@selected)][.="[trans]Choice&A[/trans]"]
  513         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  514     ]
  515     [count(./option)=3]
  516 '
  517         );
  518     }
  519 
  520     public function testSingleChoiceNonRequiredWithPlaceholder()
  521     {
  522         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  523             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  524             'multiple' => false,
  525             'expanded' => false,
  526             'required' => false,
  527             'placeholder' => 'Select&Anything&Not&Me',
  528         ]);
  529 
  530         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  531 '/select
  532     [@name="name"]
  533     [@class="my&class form-control"]
  534     [not(@required)]
  535     [
  536         ./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Select&Anything&Not&Me[/trans]"]
  537         /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  538         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  539     ]
  540     [count(./option)=3]
  541 '
  542         );
  543     }
  544 
  545     public function testSingleChoiceRequiredWithPlaceholder()
  546     {
  547         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  548             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  549             'required' => true,
  550             'multiple' => false,
  551             'expanded' => false,
  552             'placeholder' => 'Test&Me',
  553         ]);
  554 
  555         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  556 '/select
  557     [@name="name"]
  558     [@class="my&class form-control"]
  559     [@required="required"]
  560     [
  561         ./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Test&Me[/trans]"]
  562         /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  563         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  564     ]
  565     [count(./option)=3]
  566 '
  567         );
  568     }
  569 
  570     public function testSingleChoiceRequiredWithPlaceholderViaView()
  571     {
  572         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  573             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  574             'required' => true,
  575             'multiple' => false,
  576             'expanded' => false,
  577         ]);
  578 
  579         $this->assertWidgetMatchesXpath($form->createView(), ['placeholder' => '', 'attr' => ['class' => 'my&class']],
  580 '/select
  581     [@name="name"]
  582     [@class="my&class form-control"]
  583     [@required="required"]
  584     [
  585         ./option[@value=""][not(@selected)][not(@disabled)][.=""]
  586         /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  587         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  588     ]
  589     [count(./option)=3]
  590 '
  591         );
  592     }
  593 
  594     public function testSingleChoiceGrouped()
  595     {
  596         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  597             'choices' => [
  598                 'Group&1' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  599                 'Group&2' => ['Choice&C' => '&c'],
  600             ],
  601             'multiple' => false,
  602             'expanded' => false,
  603         ]);
  604 
  605         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  606 '/select
  607     [@name="name"]
  608     [@class="my&class form-control"]
  609     [./optgroup[@label="[trans]Group&1[/trans]"]
  610         [
  611             ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  612             /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  613         ]
  614         [count(./option)=2]
  615     ]
  616     [./optgroup[@label="[trans]Group&2[/trans]"]
  617         [./option[@value="&c"][not(@selected)][.="[trans]Choice&C[/trans]"]]
  618         [count(./option)=1]
  619     ]
  620     [count(./optgroup)=2]
  621 '
  622         );
  623     }
  624 
  625     public function testMultipleChoice()
  626     {
  627         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a'], [
  628             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  629             'required' => true,
  630             'multiple' => true,
  631             'expanded' => false,
  632         ]);
  633 
  634         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  635 '/select
  636     [@name="name[]"]
  637     [@class="my&class form-control"]
  638     [@required="required"]
  639     [@multiple="multiple"]
  640     [
  641         ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  642         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  643     ]
  644     [count(./option)=2]
  645 '
  646         );
  647     }
  648 
  649     public function testMultipleChoiceAttributes()
  650     {
  651         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a'], [
  652             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  653             'choice_attr' => ['Choice&B' => ['class' => 'foo&bar']],
  654             'required' => true,
  655             'multiple' => true,
  656             'expanded' => false,
  657         ]);
  658 
  659         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  660 '/select
  661     [@name="name[]"]
  662     [@class="my&class form-control"]
  663     [@required="required"]
  664     [@multiple="multiple"]
  665     [
  666         ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  667         /following-sibling::option[@value="&b"][@class="foo&bar"][not(@selected)][.="[trans]Choice&B[/trans]"]
  668     ]
  669     [count(./option)=2]
  670 '
  671         );
  672     }
  673 
  674     public function testMultipleChoiceSkipsPlaceholder()
  675     {
  676         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a'], [
  677             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  678             'multiple' => true,
  679             'expanded' => false,
  680             'placeholder' => 'Test&Me',
  681         ]);
  682 
  683         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  684 '/select
  685     [@name="name[]"]
  686     [@class="my&class form-control"]
  687     [@multiple="multiple"]
  688     [
  689         ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  690         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  691     ]
  692     [count(./option)=2]
  693 '
  694         );
  695     }
  696 
  697     public function testMultipleChoiceNonRequired()
  698     {
  699         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a'], [
  700             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  701             'required' => false,
  702             'multiple' => true,
  703             'expanded' => false,
  704         ]);
  705 
  706         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
  707 '/select
  708     [@name="name[]"]
  709     [@class="my&class form-control"]
  710     [@multiple="multiple"]
  711     [
  712         ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
  713         /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
  714     ]
  715     [count(./option)=2]
  716 '
  717         );
  718     }
  719 
  720     public function testSingleChoiceExpanded()
  721     {
  722         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  723             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  724             'multiple' => false,
  725             'expanded' => true,
  726         ]);
  727 
  728         $this->assertWidgetMatchesXpath($form->createView(), [],
  729 '/div
  730     [
  731         ./div
  732             [@class="radio"]
  733             [
  734                 ./label
  735                     [.=" [trans]Choice&A[/trans]"]
  736                     [
  737                         ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
  738                     ]
  739             ]
  740         /following-sibling::div
  741             [@class="radio"]
  742             [
  743                 ./label
  744                     [.=" [trans]Choice&B[/trans]"]
  745                     [
  746                         ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
  747                     ]
  748             ]
  749         /following-sibling::input[@type="hidden"][@id="name__token"]
  750     ]
  751 '
  752         );
  753     }
  754 
  755     public function testSingleChoiceExpandedWithLabelsAsFalse()
  756     {
  757         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  758             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  759             'choice_label' => false,
  760             'multiple' => false,
  761             'expanded' => true,
  762         ]);
  763 
  764         $this->assertWidgetMatchesXpath($form->createView(), [],
  765 '/div
  766     [
  767         ./div
  768             [@class="radio"]
  769             [
  770                 ./label
  771                     [
  772                         ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
  773                     ]
  774             ]
  775         /following-sibling::div
  776             [@class="radio"]
  777             [
  778                 ./label
  779                     [
  780                         ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
  781                     ]
  782             ]
  783         /following-sibling::input[@type="hidden"][@id="name__token"]
  784     ]
  785 '
  786         );
  787     }
  788 
  789     public function testSingleChoiceExpandedWithLabelsSetByCallable()
  790     {
  791         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  792             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'],
  793             'choice_label' => function ($choice, $label, $value) {
  794                 if ('&b' === $choice) {
  795                     return false;
  796                 }
  797 
  798                 return 'label.'.$value;
  799             },
  800             'multiple' => false,
  801             'expanded' => true,
  802         ]);
  803 
  804         $this->assertWidgetMatchesXpath($form->createView(), [],
  805 '/div
  806     [
  807         ./div
  808             [@class="radio"]
  809             [
  810                 ./label
  811                     [.=" [trans]label.&a[/trans]"]
  812                     [
  813                         ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
  814                     ]
  815             ]
  816         /following-sibling::div
  817             [@class="radio"]
  818             [
  819                 ./label
  820                     [
  821                         ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
  822                     ]
  823             ]
  824         /following-sibling::div
  825             [@class="radio"]
  826             [
  827                 ./label
  828                     [.=" [trans]label.&c[/trans]"]
  829                     [
  830                         ./input[@type="radio"][@name="name"][@id="name_2"][@value="&c"][not(@checked)]
  831                     ]
  832             ]
  833         /following-sibling::input[@type="hidden"][@id="name__token"]
  834     ]
  835 '
  836         );
  837     }
  838 
  839     public function testSingleChoiceExpandedWithLabelsSetFalseByCallable()
  840     {
  841         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  842             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  843             'choice_label' => function () {
  844                 return false;
  845             },
  846             'multiple' => false,
  847             'expanded' => true,
  848         ]);
  849 
  850         $this->assertWidgetMatchesXpath($form->createView(), [],
  851 '/div
  852     [
  853         ./div
  854             [@class="radio"]
  855             [
  856                 ./label
  857                     [
  858                         ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
  859                     ]
  860             ]
  861         /following-sibling::div
  862             [@class="radio"]
  863             [
  864                 ./label
  865                     [
  866                         ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
  867                     ]
  868             ]
  869         /following-sibling::input[@type="hidden"][@id="name__token"]
  870     ]
  871 '
  872         );
  873     }
  874 
  875     public function testSingleChoiceExpandedWithoutTranslation()
  876     {
  877         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  878             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  879             'multiple' => false,
  880             'expanded' => true,
  881             'choice_translation_domain' => false,
  882         ]);
  883 
  884         $this->assertWidgetMatchesXpath($form->createView(), [],
  885 '/div
  886     [
  887         ./div
  888             [@class="radio"]
  889             [
  890                 ./label
  891                     [.=" Choice&A"]
  892                     [
  893                         ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
  894                     ]
  895             ]
  896         /following-sibling::div
  897             [@class="radio"]
  898             [
  899                 ./label
  900                     [.=" Choice&B"]
  901                     [
  902                         ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
  903                     ]
  904             ]
  905         /following-sibling::input[@type="hidden"][@id="name__token"]
  906     ]
  907 '
  908         );
  909     }
  910 
  911     public function testSingleChoiceExpandedAttributes()
  912     {
  913         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  914             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  915             'choice_attr' => ['Choice&B' => ['class' => 'foo&bar']],
  916             'multiple' => false,
  917             'expanded' => true,
  918         ]);
  919 
  920         $this->assertWidgetMatchesXpath($form->createView(), [],
  921 '/div
  922     [
  923         ./div
  924             [@class="radio"]
  925             [
  926                 ./label
  927                     [.=" [trans]Choice&A[/trans]"]
  928                     [
  929                         ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
  930                     ]
  931             ]
  932         /following-sibling::div
  933             [@class="radio"]
  934             [
  935                 ./label
  936                     [.=" [trans]Choice&B[/trans]"]
  937                     [
  938                         ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)][@class="foo&bar"]
  939                     ]
  940             ]
  941         /following-sibling::input[@type="hidden"][@id="name__token"]
  942     ]
  943 '
  944         );
  945     }
  946 
  947     public function testSingleChoiceExpandedWithPlaceholder()
  948     {
  949         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  950             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  951             'multiple' => false,
  952             'expanded' => true,
  953             'placeholder' => 'Test&Me',
  954             'required' => false,
  955         ]);
  956 
  957         $this->assertWidgetMatchesXpath($form->createView(), [],
  958 '/div
  959     [
  960         ./div
  961             [@class="radio"]
  962             [
  963                 ./label
  964                     [.=" [trans]Test&Me[/trans]"]
  965                     [
  966                         ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
  967                     ]
  968             ]
  969         /following-sibling::div
  970             [@class="radio"]
  971             [
  972                 ./label
  973                     [.=" [trans]Choice&A[/trans]"]
  974                     [
  975                         ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
  976                     ]
  977             ]
  978         /following-sibling::div
  979             [@class="radio"]
  980             [
  981                 ./label
  982                     [.=" [trans]Choice&B[/trans]"]
  983                     [
  984                         ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
  985                     ]
  986             ]
  987         /following-sibling::input[@type="hidden"][@id="name__token"]
  988     ]
  989 '
  990         );
  991     }
  992 
  993     public function testSingleChoiceExpandedWithPlaceholderWithoutTranslation()
  994     {
  995         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
  996             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
  997             'multiple' => false,
  998             'expanded' => true,
  999             'required' => false,
 1000             'choice_translation_domain' => false,
 1001             'placeholder' => 'Placeholder&Not&Translated',
 1002         ]);
 1003 
 1004         $this->assertWidgetMatchesXpath($form->createView(), [],
 1005 '/div
 1006     [
 1007         ./div
 1008             [@class="radio"]
 1009             [
 1010                 ./label
 1011                     [.=" Placeholder&Not&Translated"]
 1012                     [
 1013                         ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
 1014                     ]
 1015             ]
 1016         /following-sibling::div
 1017             [@class="radio"]
 1018             [
 1019                 ./label
 1020                     [.=" Choice&A"]
 1021                     [
 1022                         ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
 1023                     ]
 1024             ]
 1025         /following-sibling::div
 1026             [@class="radio"]
 1027             [
 1028                 ./label
 1029                     [.=" Choice&B"]
 1030                     [
 1031                         ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
 1032                     ]
 1033             ]
 1034         /following-sibling::input[@type="hidden"][@id="name__token"]
 1035     ]
 1036 '
 1037         );
 1038     }
 1039 
 1040     public function testSingleChoiceExpandedWithBooleanValue()
 1041     {
 1042         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', true, [
 1043             'choices' => ['Choice&A' => '1', 'Choice&B' => '0'],
 1044             'multiple' => false,
 1045             'expanded' => true,
 1046         ]);
 1047 
 1048         $this->assertWidgetMatchesXpath($form->createView(), [],
 1049 '/div
 1050     [
 1051         ./div
 1052             [@class="radio"]
 1053             [
 1054                 ./label
 1055                     [.=" [trans]Choice&A[/trans]"]
 1056                     [
 1057                         ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
 1058                     ]
 1059             ]
 1060         /following-sibling::div
 1061             [@class="radio"]
 1062             [
 1063                 ./label
 1064                     [.=" [trans]Choice&B[/trans]"]
 1065                     [
 1066                         ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
 1067                     ]
 1068             ]
 1069         /following-sibling::input[@type="hidden"][@id="name__token"]
 1070     ]
 1071 '
 1072         );
 1073     }
 1074 
 1075     public function testMultipleChoiceExpanded()
 1076     {
 1077         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a', '&c'], [
 1078             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'],
 1079             'multiple' => true,
 1080             'expanded' => true,
 1081             'required' => true,
 1082         ]);
 1083 
 1084         $this->assertWidgetMatchesXpath($form->createView(), [],
 1085 '/div
 1086     [
 1087         ./div
 1088             [@class="checkbox"]
 1089             [
 1090                 ./label
 1091                     [.=" [trans]Choice&A[/trans]"]
 1092                     [
 1093                         ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
 1094                     ]
 1095             ]
 1096         /following-sibling::div
 1097             [@class="checkbox"]
 1098             [
 1099                 ./label
 1100                     [.=" [trans]Choice&B[/trans]"]
 1101                     [
 1102                         ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
 1103                     ]
 1104             ]
 1105         /following-sibling::div
 1106             [@class="checkbox"]
 1107             [
 1108                 ./label
 1109                     [.=" [trans]Choice&C[/trans]"]
 1110                     [
 1111                         ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
 1112                     ]
 1113             ]
 1114         /following-sibling::input[@type="hidden"][@id="name__token"]
 1115     ]
 1116 '
 1117         );
 1118     }
 1119 
 1120     public function testMultipleChoiceExpandedWithLabelsAsFalse()
 1121     {
 1122         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a'], [
 1123             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
 1124             'choice_label' => false,
 1125             'multiple' => true,
 1126             'expanded' => true,
 1127         ]);
 1128 
 1129         $this->assertWidgetMatchesXpath($form->createView(), [],
 1130 '/div
 1131     [
 1132         ./div
 1133             [@class="checkbox"]
 1134             [
 1135                 ./label
 1136                     [
 1137                         ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
 1138                     ]
 1139             ]
 1140         /following-sibling::div
 1141             [@class="checkbox"]
 1142             [
 1143                 ./label
 1144                     [
 1145                         ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
 1146                     ]
 1147             ]
 1148         /following-sibling::input[@type="hidden"][@id="name__token"]
 1149     ]
 1150 '
 1151         );
 1152     }
 1153 
 1154     public function testMultipleChoiceExpandedWithLabelsSetByCallable()
 1155     {
 1156         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a'], [
 1157             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'],
 1158             'choice_label' => function ($choice, $label, $value) {
 1159                 if ('&b' === $choice) {
 1160                     return false;
 1161                 }
 1162 
 1163                 return 'label.'.$value;
 1164             },
 1165             'multiple' => true,
 1166             'expanded' => true,
 1167         ]);
 1168 
 1169         $this->assertWidgetMatchesXpath($form->createView(), [],
 1170             '/div
 1171     [
 1172         ./div
 1173             [@class="checkbox"]
 1174             [
 1175                 ./label
 1176                     [.=" [trans]label.&a[/trans]"]
 1177                     [
 1178                         ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
 1179                     ]
 1180             ]
 1181         /following-sibling::div
 1182             [@class="checkbox"]
 1183             [
 1184                 ./label
 1185                     [
 1186                         ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
 1187                     ]
 1188             ]
 1189         /following-sibling::div
 1190             [@class="checkbox"]
 1191             [
 1192                 ./label
 1193                     [.=" [trans]label.&c[/trans]"]
 1194                     [
 1195                         ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@value="&c"][not(@checked)]
 1196                     ]
 1197             ]
 1198         /following-sibling::input[@type="hidden"][@id="name__token"]
 1199     ]
 1200 '
 1201         );
 1202     }
 1203 
 1204     public function testMultipleChoiceExpandedWithLabelsSetFalseByCallable()
 1205     {
 1206         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a'], [
 1207             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b'],
 1208             'choice_label' => function () {
 1209                 return false;
 1210             },
 1211             'multiple' => true,
 1212             'expanded' => true,
 1213         ]);
 1214 
 1215         $this->assertWidgetMatchesXpath($form->createView(), [],
 1216 '/div
 1217     [
 1218         ./div
 1219             [@class="checkbox"]
 1220             [
 1221                 ./label
 1222                     [
 1223                         ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
 1224                     ]
 1225             ]
 1226         /following-sibling::div
 1227             [@class="checkbox"]
 1228             [
 1229                 ./label
 1230                     [
 1231                         ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
 1232                     ]
 1233             ]
 1234         /following-sibling::input[@type="hidden"][@id="name__token"]
 1235     ]
 1236 '
 1237         );
 1238     }
 1239 
 1240     public function testMultipleChoiceExpandedWithoutTranslation()
 1241     {
 1242         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a', '&c'], [
 1243             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'],
 1244             'multiple' => true,
 1245             'expanded' => true,
 1246             'required' => true,
 1247             'choice_translation_domain' => false,
 1248         ]);
 1249 
 1250         $this->assertWidgetMatchesXpath($form->createView(), [],
 1251 '/div
 1252     [
 1253         ./div
 1254             [@class="checkbox"]
 1255             [
 1256                 ./label
 1257                     [.=" Choice&A"]
 1258                     [
 1259                         ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
 1260                     ]
 1261             ]
 1262         /following-sibling::div
 1263             [@class="checkbox"]
 1264             [
 1265                 ./label
 1266                     [.=" Choice&B"]
 1267                     [
 1268                         ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
 1269                     ]
 1270             ]
 1271         /following-sibling::div
 1272             [@class="checkbox"]
 1273             [
 1274                 ./label
 1275                     [.=" Choice&C"]
 1276                     [
 1277                         ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
 1278                     ]
 1279             ]
 1280         /following-sibling::input[@type="hidden"][@id="name__token"]
 1281     ]
 1282 '
 1283         );
 1284     }
 1285 
 1286     public function testMultipleChoiceExpandedAttributes()
 1287     {
 1288         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', ['&a', '&c'], [
 1289             'choices' => ['Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'],
 1290             'choice_attr' => ['Choice&B' => ['class' => 'foo&bar']],
 1291             'multiple' => true,
 1292             'expanded' => true,
 1293             'required' => true,
 1294         ]);
 1295 
 1296         $this->assertWidgetMatchesXpath($form->createView(), [],
 1297 '/div
 1298     [
 1299         ./div
 1300             [@class="checkbox"]
 1301             [
 1302                 ./label
 1303                     [.=" [trans]Choice&A[/trans]"]
 1304                     [
 1305                         ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
 1306                     ]
 1307             ]
 1308         /following-sibling::div
 1309             [@class="checkbox"]
 1310             [
 1311                 ./label
 1312                     [.=" [trans]Choice&B[/trans]"]
 1313                     [
 1314                         ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)][@class="foo&bar"]
 1315                     ]
 1316             ]
 1317         /following-sibling::div
 1318             [@class="checkbox"]
 1319             [
 1320                 ./label
 1321                     [.=" [trans]Choice&C[/trans]"]
 1322                     [
 1323                         ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
 1324                     ]
 1325             ]
 1326         /following-sibling::input[@type="hidden"][@id="name__token"]
 1327     ]
 1328 '
 1329         );
 1330     }
 1331 
 1332     public function testCountry()
 1333     {
 1334         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CountryType', 'AT');
 1335 
 1336         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1337 '/select
 1338     [@name="name"]
 1339     [@class="my&class form-control"]
 1340     [./option[@value="AT"][@selected="selected"][.="Austria"]]
 1341     [count(./option)>200]
 1342 '
 1343         );
 1344     }
 1345 
 1346     public function testCountryWithPlaceholder()
 1347     {
 1348         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CountryType', 'AT', [
 1349             'placeholder' => 'Select&Country',
 1350             'required' => false,
 1351         ]);
 1352 
 1353         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1354 '/select
 1355     [@name="name"]
 1356     [@class="my&class form-control"]
 1357     [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Select&Country[/trans]"]]
 1358     [./option[@value="AT"][@selected="selected"][.="Austria"]]
 1359     [count(./option)>201]
 1360 '
 1361         );
 1362     }
 1363 
 1364     public function testDateTime()
 1365     {
 1366         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', date('Y').'-02-03 04:05:06', [
 1367             'input' => 'string',
 1368             'with_seconds' => false,
 1369         ]);
 1370 
 1371         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1372 '/div
 1373     [
 1374         ./select
 1375             [@id="name_date_month"]
 1376             [@class="form-control"]
 1377             [./option[@value="2"][@selected="selected"]]
 1378         /following-sibling::select
 1379             [@id="name_date_day"]
 1380             [@class="form-control"]
 1381             [./option[@value="3"][@selected="selected"]]
 1382         /following-sibling::select
 1383             [@id="name_date_year"]
 1384             [@class="form-control"]
 1385             [./option[@value="'.date('Y').'"][@selected="selected"]]
 1386         /following-sibling::select
 1387             [@id="name_time_hour"]
 1388             [@class="form-control"]
 1389             [./option[@value="4"][@selected="selected"]]
 1390         /following-sibling::select
 1391             [@id="name_time_minute"]
 1392             [@class="form-control"]
 1393             [./option[@value="5"][@selected="selected"]]
 1394     ]
 1395     [count(.//select)=5]
 1396 '
 1397         );
 1398     }
 1399 
 1400     public function testDateTimeWithPlaceholderGlobal()
 1401     {
 1402         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', null, [
 1403             'input' => 'string',
 1404             'placeholder' => 'Change&Me',
 1405             'required' => false,
 1406         ]);
 1407 
 1408         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1409 '/div
 1410     [@class="my&class form-inline"]
 1411     [
 1412         ./select
 1413             [@id="name_date_month"]
 1414             [@class="form-control"]
 1415             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 1416         /following-sibling::select
 1417             [@id="name_date_day"]
 1418             [@class="form-control"]
 1419             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 1420         /following-sibling::select
 1421             [@id="name_date_year"]
 1422             [@class="form-control"]
 1423             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 1424         /following-sibling::select
 1425             [@id="name_time_hour"]
 1426             [@class="form-control"]
 1427             [./option[@value=""][.="[trans]Change&Me[/trans]"]]
 1428         /following-sibling::select
 1429             [@id="name_time_minute"]
 1430             [@class="form-control"]
 1431             [./option[@value=""][.="[trans]Change&Me[/trans]"]]
 1432     ]
 1433     [count(.//select)=5]
 1434 '
 1435         );
 1436     }
 1437 
 1438     public function testDateTimeWithHourAndMinute()
 1439     {
 1440         $data = ['year' => date('Y'), 'month' => '2', 'day' => '3', 'hour' => '4', 'minute' => '5'];
 1441 
 1442         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', $data, [
 1443             'input' => 'array',
 1444             'required' => false,
 1445         ]);
 1446 
 1447         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1448 '/div
 1449     [@class="my&class form-inline"]
 1450     [
 1451         ./select
 1452             [@id="name_date_month"]
 1453             [@class="form-control"]
 1454             [./option[@value="2"][@selected="selected"]]
 1455         /following-sibling::select
 1456             [@id="name_date_day"]
 1457             [@class="form-control"]
 1458             [./option[@value="3"][@selected="selected"]]
 1459         /following-sibling::select
 1460             [@id="name_date_year"]
 1461             [@class="form-control"]
 1462             [./option[@value="'.date('Y').'"][@selected="selected"]]
 1463         /following-sibling::select
 1464             [@id="name_time_hour"]
 1465             [@class="form-control"]
 1466             [./option[@value="4"][@selected="selected"]]
 1467         /following-sibling::select
 1468             [@id="name_time_minute"]
 1469             [@class="form-control"]
 1470             [./option[@value="5"][@selected="selected"]]
 1471     ]
 1472     [count(.//select)=5]
 1473 '
 1474         );
 1475     }
 1476 
 1477     public function testDateTimeWithSeconds()
 1478     {
 1479         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', date('Y').'-02-03 04:05:06', [
 1480             'input' => 'string',
 1481             'with_seconds' => true,
 1482         ]);
 1483 
 1484         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1485 '/div
 1486     [@class="my&class form-inline"]
 1487     [
 1488         ./select
 1489             [@id="name_date_month"]
 1490             [@class="form-control"]
 1491             [./option[@value="2"][@selected="selected"]]
 1492         /following-sibling::select
 1493             [@id="name_date_day"]
 1494             [@class="form-control"]
 1495             [./option[@value="3"][@selected="selected"]]
 1496         /following-sibling::select
 1497             [@id="name_date_year"]
 1498             [@class="form-control"]
 1499             [./option[@value="'.date('Y').'"][@selected="selected"]]
 1500         /following-sibling::select
 1501             [@id="name_time_hour"]
 1502             [@class="form-control"]
 1503             [./option[@value="4"][@selected="selected"]]
 1504         /following-sibling::select
 1505             [@id="name_time_minute"]
 1506             [@class="form-control"]
 1507             [./option[@value="5"][@selected="selected"]]
 1508         /following-sibling::select
 1509             [@id="name_time_second"]
 1510             [@class="form-control"]
 1511             [./option[@value="6"][@selected="selected"]]
 1512     ]
 1513     [count(.//select)=6]
 1514 '
 1515         );
 1516     }
 1517 
 1518     public function testDateTimeSingleText()
 1519     {
 1520         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', '2011-02-03 04:05:06', [
 1521             'input' => 'string',
 1522             'date_widget' => 'single_text',
 1523             'time_widget' => 'single_text',
 1524         ]);
 1525 
 1526         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1527 '/div
 1528     [@class="my&class form-inline"]
 1529     [
 1530         ./input
 1531             [@type="date"]
 1532             [@id="name_date"]
 1533             [@name="name[date]"]
 1534             [@class="form-control"]
 1535             [@value="2011-02-03"]
 1536         /following-sibling::input
 1537             [@type="time"]
 1538             [@id="name_time"]
 1539             [@name="name[time]"]
 1540             [@class="form-control"]
 1541             [@value="04:05"]
 1542     ]
 1543 '
 1544         );
 1545     }
 1546 
 1547     public function testDateTimeWithWidgetSingleText()
 1548     {
 1549         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', '2011-02-03 04:05:06', [
 1550             'input' => 'string',
 1551             'widget' => 'single_text',
 1552             'model_timezone' => 'UTC',
 1553             'view_timezone' => 'UTC',
 1554         ]);
 1555 
 1556         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1557 '/input
 1558     [@type="datetime-local"]
 1559     [@name="name"]
 1560     [@class="my&class form-control"]
 1561     [@value="2011-02-03T04:05:06"]
 1562 '
 1563         );
 1564     }
 1565 
 1566     public function testDateTimeWithWidgetSingleTextIgnoreDateAndTimeWidgets()
 1567     {
 1568         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', '2011-02-03 04:05:06', [
 1569             'input' => 'string',
 1570             'date_widget' => 'choice',
 1571             'time_widget' => 'choice',
 1572             'widget' => 'single_text',
 1573             'model_timezone' => 'UTC',
 1574             'view_timezone' => 'UTC',
 1575         ]);
 1576 
 1577         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1578 '/input
 1579     [@type="datetime-local"]
 1580     [@name="name"]
 1581     [@class="my&class form-control"]
 1582     [@value="2011-02-03T04:05:06"]
 1583 '
 1584         );
 1585     }
 1586 
 1587     public function testDateChoice()
 1588     {
 1589         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType', date('Y').'-02-03', [
 1590             'input' => 'string',
 1591             'widget' => 'choice',
 1592         ]);
 1593 
 1594         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1595 '/div
 1596     [@class="my&class form-inline"]
 1597     [
 1598         ./select
 1599             [@id="name_month"]
 1600             [@class="form-control"]
 1601             [./option[@value="2"][@selected="selected"]]
 1602         /following-sibling::select
 1603             [@id="name_day"]
 1604             [@class="form-control"]
 1605             [./option[@value="3"][@selected="selected"]]
 1606         /following-sibling::select
 1607             [@id="name_year"]
 1608             [@class="form-control"]
 1609             [./option[@value="'.date('Y').'"][@selected="selected"]]
 1610     ]
 1611     [count(./select)=3]
 1612 '
 1613         );
 1614     }
 1615 
 1616     public function testDateChoiceWithPlaceholderGlobal()
 1617     {
 1618         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType', null, [
 1619             'input' => 'string',
 1620             'widget' => 'choice',
 1621             'placeholder' => 'Change&Me',
 1622             'required' => false,
 1623         ]);
 1624 
 1625         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1626 '/div
 1627     [@class="my&class form-inline"]
 1628     [
 1629         ./select
 1630             [@id="name_month"]
 1631             [@class="form-control"]
 1632             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 1633         /following-sibling::select
 1634             [@id="name_day"]
 1635             [@class="form-control"]
 1636             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 1637         /following-sibling::select
 1638             [@id="name_year"]
 1639             [@class="form-control"]
 1640             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 1641     ]
 1642     [count(./select)=3]
 1643 '
 1644         );
 1645     }
 1646 
 1647     public function testDateChoiceWithPlaceholderOnYear()
 1648     {
 1649         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType', null, [
 1650             'input' => 'string',
 1651             'widget' => 'choice',
 1652             'required' => false,
 1653             'placeholder' => ['year' => 'Change&Me'],
 1654         ]);
 1655 
 1656         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1657 '/div
 1658     [@class="my&class form-inline"]
 1659     [
 1660         ./select
 1661             [@id="name_month"]
 1662             [@class="form-control"]
 1663             [./option[@value="1"]]
 1664         /following-sibling::select
 1665             [@id="name_day"]
 1666             [@class="form-control"]
 1667             [./option[@value="1"]]
 1668         /following-sibling::select
 1669             [@id="name_year"]
 1670             [@class="form-control"]
 1671             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 1672     ]
 1673     [count(./select)=3]
 1674 '
 1675         );
 1676     }
 1677 
 1678     public function testDateText()
 1679     {
 1680         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType', '2011-02-03', [
 1681             'input' => 'string',
 1682             'widget' => 'text',
 1683         ]);
 1684 
 1685         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1686 '/div
 1687     [@class="my&class form-inline"]
 1688     [
 1689         ./input
 1690             [@id="name_month"]
 1691             [@type="text"]
 1692             [@class="form-control"]
 1693             [@value="2"]
 1694         /following-sibling::input
 1695             [@id="name_day"]
 1696             [@type="text"]
 1697             [@class="form-control"]
 1698             [@value="3"]
 1699         /following-sibling::input
 1700             [@id="name_year"]
 1701             [@type="text"]
 1702             [@class="form-control"]
 1703             [@value="2011"]
 1704     ]
 1705     [count(./input)=3]
 1706 '
 1707         );
 1708     }
 1709 
 1710     public function testDateSingleText()
 1711     {
 1712         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType', '2011-02-03', [
 1713             'input' => 'string',
 1714             'widget' => 'single_text',
 1715         ]);
 1716 
 1717         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1718 '/input
 1719     [@type="date"]
 1720     [@name="name"]
 1721     [@class="my&class form-control"]
 1722     [@value="2011-02-03"]
 1723 '
 1724         );
 1725     }
 1726 
 1727     public function testBirthDay()
 1728     {
 1729         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\BirthdayType', '2000-02-03', [
 1730             'input' => 'string',
 1731         ]);
 1732 
 1733         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1734 '/div
 1735     [@class="my&class form-inline"]
 1736     [
 1737         ./select
 1738             [@id="name_month"]
 1739             [@class="form-control"]
 1740             [./option[@value="2"][@selected="selected"]]
 1741         /following-sibling::select
 1742             [@id="name_day"]
 1743             [@class="form-control"]
 1744             [./option[@value="3"][@selected="selected"]]
 1745         /following-sibling::select
 1746             [@id="name_year"]
 1747             [@class="form-control"]
 1748             [./option[@value="2000"][@selected="selected"]]
 1749     ]
 1750     [count(./select)=3]
 1751 '
 1752         );
 1753     }
 1754 
 1755     public function testBirthDayWithPlaceholder()
 1756     {
 1757         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\BirthdayType', '1950-01-01', [
 1758             'input' => 'string',
 1759             'placeholder' => '',
 1760             'required' => false,
 1761         ]);
 1762 
 1763         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1764 '/div
 1765     [@class="my&class form-inline"]
 1766     [
 1767         ./select
 1768             [@id="name_month"]
 1769             [@class="form-control"]
 1770             [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
 1771             [./option[@value="1"][@selected="selected"]]
 1772         /following-sibling::select
 1773             [@id="name_day"]
 1774             [@class="form-control"]
 1775             [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
 1776             [./option[@value="1"][@selected="selected"]]
 1777         /following-sibling::select
 1778             [@id="name_year"]
 1779             [@class="form-control"]
 1780             [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
 1781             [./option[@value="1950"][@selected="selected"]]
 1782     ]
 1783     [count(./select)=3]
 1784 '
 1785         );
 1786     }
 1787 
 1788     public function testEmail()
 1789     {
 1790         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\EmailType', 'foo&bar');
 1791 
 1792         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1793 '/input
 1794     [@type="email"]
 1795     [@name="name"]
 1796     [@class="my&class form-control"]
 1797     [@value="foo&bar"]
 1798     [not(@maxlength)]
 1799 '
 1800         );
 1801     }
 1802 
 1803     public function testEmailWithMaxLength()
 1804     {
 1805         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\EmailType', 'foo&bar', [
 1806             'attr' => ['maxlength' => 123],
 1807         ]);
 1808 
 1809         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1810 '/input
 1811     [@type="email"]
 1812     [@name="name"]
 1813     [@class="my&class form-control"]
 1814     [@value="foo&bar"]
 1815     [@maxlength="123"]
 1816 '
 1817         );
 1818     }
 1819 
 1820     public function testHidden()
 1821     {
 1822         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\HiddenType', 'foo&bar');
 1823 
 1824         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1825 '/input
 1826     [@type="hidden"]
 1827     [@name="name"]
 1828     [@class="my&class"]
 1829     [@value="foo&bar"]
 1830 '
 1831         );
 1832     }
 1833 
 1834     public function testDisabled()
 1835     {
 1836         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', null, [
 1837             'disabled' => true,
 1838         ]);
 1839 
 1840         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1841 '/input
 1842     [@type="text"]
 1843     [@name="name"]
 1844     [@class="my&class form-control"]
 1845     [@disabled="disabled"]
 1846 '
 1847         );
 1848     }
 1849 
 1850     public function testInteger()
 1851     {
 1852         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\IntegerType', 123);
 1853 
 1854         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1855 '/input
 1856     [@type="number"]
 1857     [@name="name"]
 1858     [@class="my&class form-control"]
 1859     [@value="123"]
 1860 '
 1861         );
 1862     }
 1863 
 1864     public function testIntegerTypeWithGroupingRendersAsTextInput()
 1865     {
 1866         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\IntegerType', 123, [
 1867             'grouping' => true,
 1868         ]);
 1869 
 1870         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1871 '/input
 1872     [@type="text"]
 1873     [@name="name"]
 1874     [@class="my&class form-control"]
 1875     [@value="123"]
 1876 '
 1877         );
 1878     }
 1879 
 1880     public function testLanguage()
 1881     {
 1882         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\LanguageType', 'de');
 1883 
 1884         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1885 '/select
 1886     [@name="name"]
 1887     [@class="my&class form-control"]
 1888     [./option[@value="de"][@selected="selected"][.="German"]]
 1889     [count(./option)>200]
 1890 '
 1891         );
 1892     }
 1893 
 1894     public function testLocale()
 1895     {
 1896         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\LocaleType', 'de_AT');
 1897 
 1898         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1899 '/select
 1900     [@name="name"]
 1901     [@class="my&class form-control"]
 1902     [./option[@value="de_AT"][@selected="selected"][.="German (Austria)"]]
 1903     [count(./option)>200]
 1904 '
 1905         );
 1906     }
 1907 
 1908     public function testMoney()
 1909     {
 1910         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\MoneyType', 1234.56, [
 1911             'currency' => 'EUR',
 1912         ]);
 1913 
 1914         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
 1915 '/div
 1916     [@class="input-group"]
 1917     [
 1918         ./span
 1919             [@class="input-group-addon"]
 1920             [contains(.., "€")]
 1921         /following-sibling::input
 1922             [@id="my&id"]
 1923             [@type="text"]
 1924             [@name="name"]
 1925             [@class="my&class form-control"]
 1926             [@value="1234.56"]
 1927     ]
 1928 '
 1929         );
 1930     }
 1931 
 1932     public function testMoneyWithoutCurrency()
 1933     {
 1934         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\MoneyType', 1234.56, [
 1935             'currency' => false,
 1936         ]);
 1937 
 1938         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
 1939 '/input
 1940     [@id="my&id"]
 1941     [@type="text"]
 1942     [@name="name"]
 1943     [@class="my&class form-control"]
 1944     [@value="1234.56"]
 1945     [not(preceding-sibling::*)]
 1946     [not(following-sibling::*)]
 1947 '
 1948         );
 1949     }
 1950 
 1951     public function testNumber()
 1952     {
 1953         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\NumberType', 1234.56);
 1954 
 1955         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1956 '/input
 1957     [@type="text"]
 1958     [@name="name"]
 1959     [@class="my&class form-control"]
 1960     [@value="1234.56"]
 1961 '
 1962         );
 1963     }
 1964 
 1965     public function testPassword()
 1966     {
 1967         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'foo&bar');
 1968 
 1969         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1970 '/input
 1971     [@type="password"]
 1972     [@name="name"]
 1973     [@class="my&class form-control"]
 1974 '
 1975         );
 1976     }
 1977 
 1978     public function testPasswordSubmittedWithNotAlwaysEmpty()
 1979     {
 1980         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', null, [
 1981             'always_empty' => false,
 1982         ]);
 1983         $form->submit('foo&bar');
 1984 
 1985         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 1986 '/input
 1987     [@type="password"]
 1988     [@name="name"]
 1989     [@class="my&class form-control"]
 1990     [@value="foo&bar"]
 1991 '
 1992         );
 1993     }
 1994 
 1995     public function testPasswordWithMaxLength()
 1996     {
 1997         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'foo&bar', [
 1998             'attr' => ['maxlength' => 123],
 1999         ]);
 2000 
 2001         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2002 '/input
 2003     [@type="password"]
 2004     [@name="name"]
 2005     [@class="my&class form-control"]
 2006     [@maxlength="123"]
 2007 '
 2008         );
 2009     }
 2010 
 2011     public function testPercent()
 2012     {
 2013         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PercentType', 0.1);
 2014 
 2015         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
 2016 '/div
 2017     [@class="input-group"]
 2018     [
 2019         ./input
 2020             [@id="my&id"]
 2021             [@type="text"]
 2022             [@name="name"]
 2023             [@class="my&class form-control"]
 2024             [@value="10"]
 2025         /following-sibling::span
 2026             [@class="input-group-addon"]
 2027             [contains(.., "%")]
 2028     ]
 2029 '
 2030         );
 2031     }
 2032 
 2033     public function testCheckedRadio()
 2034     {
 2035         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', true);
 2036 
 2037         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
 2038 '/div
 2039     [@class="radio"]
 2040     [
 2041         ./label
 2042             [@class="required"]
 2043             [
 2044                 ./input
 2045                     [@id="my&id"]
 2046                     [@type="radio"]
 2047                     [@name="name"]
 2048                     [@class="my&class"]
 2049                     [@checked="checked"]
 2050                     [@value="1"]
 2051             ]
 2052     ]
 2053 '
 2054         );
 2055     }
 2056 
 2057     public function testUncheckedRadio()
 2058     {
 2059         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', false);
 2060 
 2061         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
 2062 '/div
 2063     [@class="radio"]
 2064     [
 2065         ./label
 2066             [@class="required"]
 2067             [
 2068                 ./input
 2069                     [@id="my&id"]
 2070                     [@type="radio"]
 2071                     [@name="name"]
 2072                     [@class="my&class"]
 2073                     [not(@checked)]
 2074             ]
 2075     ]
 2076 '
 2077         );
 2078     }
 2079 
 2080     public function testRadioWithValue()
 2081     {
 2082         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', false, [
 2083             'value' => 'foo&bar',
 2084         ]);
 2085 
 2086         $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
 2087 '/div
 2088     [@class="radio"]
 2089     [
 2090         ./label
 2091             [@class="required"]
 2092             [
 2093                 ./input
 2094                     [@id="my&id"]
 2095                     [@type="radio"]
 2096                     [@name="name"]
 2097                     [@class="my&class"]
 2098                     [@value="foo&bar"]
 2099             ]
 2100     ]
 2101 '
 2102         );
 2103     }
 2104 
 2105     public function testRange()
 2106     {
 2107         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RangeType', 42, ['attr' => ['min' => 5]]);
 2108 
 2109         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2110 '/input
 2111     [@type="range"]
 2112     [@name="name"]
 2113     [@value="42"]
 2114     [@min="5"]
 2115     [@class="my&class form-control"]
 2116 '
 2117         );
 2118     }
 2119 
 2120     public function testRangeWithMinMaxValues()
 2121     {
 2122         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RangeType', 42, ['attr' => ['min' => 5, 'max' => 57]]);
 2123 
 2124         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2125 '/input
 2126     [@type="range"]
 2127     [@name="name"]
 2128     [@value="42"]
 2129     [@min="5"]
 2130     [@max="57"]
 2131     [@class="my&class form-control"]
 2132 '
 2133         );
 2134     }
 2135 
 2136     public function testTextarea()
 2137     {
 2138         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextareaType', 'foo&bar', [
 2139             'attr' => ['pattern' => 'foo'],
 2140         ]);
 2141 
 2142         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2143 '/textarea
 2144     [@name="name"]
 2145     [@pattern="foo"]
 2146     [@class="my&class form-control"]
 2147     [.="foo&bar"]
 2148 '
 2149         );
 2150     }
 2151 
 2152     public function testText()
 2153     {
 2154         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', 'foo&bar');
 2155 
 2156         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2157 '/input
 2158     [@type="text"]
 2159     [@name="name"]
 2160     [@class="my&class form-control"]
 2161     [@value="foo&bar"]
 2162     [not(@maxlength)]
 2163 '
 2164         );
 2165     }
 2166 
 2167     public function testTextWithMaxLength()
 2168     {
 2169         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', 'foo&bar', [
 2170             'attr' => ['maxlength' => 123],
 2171         ]);
 2172 
 2173         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2174 '/input
 2175     [@type="text"]
 2176     [@name="name"]
 2177     [@class="my&class form-control"]
 2178     [@value="foo&bar"]
 2179     [@maxlength="123"]
 2180 '
 2181         );
 2182     }
 2183 
 2184     public function testSearch()
 2185     {
 2186         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\SearchType', 'foo&bar');
 2187 
 2188         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2189 '/input
 2190     [@type="search"]
 2191     [@name="name"]
 2192     [@class="my&class form-control"]
 2193     [@value="foo&bar"]
 2194     [not(@maxlength)]
 2195 '
 2196         );
 2197     }
 2198 
 2199     public function testTime()
 2200     {
 2201         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TimeType', '04:05:06', [
 2202             'input' => 'string',
 2203             'with_seconds' => false,
 2204         ]);
 2205 
 2206         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2207 '/div
 2208     [@class="my&class form-inline"]
 2209     [
 2210         ./select
 2211             [@id="name_hour"]
 2212             [@class="form-control"]
 2213             [not(@size)]
 2214             [./option[@value="4"][@selected="selected"]]
 2215         /following-sibling::select
 2216             [@id="name_minute"]
 2217             [@class="form-control"]
 2218             [not(@size)]
 2219             [./option[@value="5"][@selected="selected"]]
 2220     ]
 2221     [count(./select)=2]
 2222 '
 2223         );
 2224     }
 2225 
 2226     public function testTimeWithSeconds()
 2227     {
 2228         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TimeType', '04:05:06', [
 2229             'input' => 'string',
 2230             'with_seconds' => true,
 2231         ]);
 2232 
 2233         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2234 '/div
 2235     [@class="my&class form-inline"]
 2236     [
 2237         ./select
 2238             [@id="name_hour"]
 2239             [@class="form-control"]
 2240             [not(@size)]
 2241             [./option[@value="4"][@selected="selected"]]
 2242             [count(./option)>23]
 2243         /following-sibling::select
 2244             [@id="name_minute"]
 2245             [@class="form-control"]
 2246             [not(@size)]
 2247             [./option[@value="5"][@selected="selected"]]
 2248             [count(./option)>59]
 2249         /following-sibling::select
 2250             [@id="name_second"]
 2251             [@class="form-control"]
 2252             [not(@size)]
 2253             [./option[@value="6"][@selected="selected"]]
 2254             [count(./option)>59]
 2255     ]
 2256     [count(./select)=3]
 2257 '
 2258         );
 2259     }
 2260 
 2261     public function testTimeText()
 2262     {
 2263         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TimeType', '04:05:06', [
 2264             'input' => 'string',
 2265             'widget' => 'text',
 2266         ]);
 2267 
 2268         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2269 '/div
 2270     [@class="my&class form-inline"]
 2271     [
 2272         ./input
 2273             [@type="text"]
 2274             [@id="name_hour"]
 2275             [@name="name[hour]"]
 2276             [@class="form-control"]
 2277             [@value="04"]
 2278             [@required="required"]
 2279             [not(@size)]
 2280         /following-sibling::input
 2281             [@type="text"]
 2282             [@id="name_minute"]
 2283             [@name="name[minute]"]
 2284             [@class="form-control"]
 2285             [@value="05"]
 2286             [@required="required"]
 2287             [not(@size)]
 2288     ]
 2289     [count(./input)=2]
 2290 '
 2291         );
 2292     }
 2293 
 2294     public function testTimeSingleText()
 2295     {
 2296         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TimeType', '04:05:06', [
 2297             'input' => 'string',
 2298             'widget' => 'single_text',
 2299         ]);
 2300 
 2301         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2302 '/input
 2303     [@type="time"]
 2304     [@name="name"]
 2305     [@class="my&class form-control"]
 2306     [@value="04:05"]
 2307     [not(@size)]
 2308 '
 2309         );
 2310     }
 2311 
 2312     public function testTimeWithPlaceholderGlobal()
 2313     {
 2314         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TimeType', null, [
 2315             'input' => 'string',
 2316             'placeholder' => 'Change&Me',
 2317             'required' => false,
 2318         ]);
 2319 
 2320         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2321 '/div
 2322     [@class="my&class form-inline"]
 2323     [
 2324         ./select
 2325             [@id="name_hour"]
 2326             [@class="form-control"]
 2327             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 2328             [count(./option)>24]
 2329         /following-sibling::select
 2330             [@id="name_minute"]
 2331             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 2332             [count(./option)>60]
 2333     ]
 2334     [count(./select)=2]
 2335 '
 2336         );
 2337     }
 2338 
 2339     public function testTimeWithPlaceholderOnYear()
 2340     {
 2341         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TimeType', null, [
 2342             'input' => 'string',
 2343             'required' => false,
 2344             'placeholder' => ['hour' => 'Change&Me'],
 2345         ]);
 2346 
 2347         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2348 '/div
 2349     [@class="my&class form-inline"]
 2350     [
 2351         ./select
 2352             [@id="name_hour"]
 2353             [@class="form-control"]
 2354             [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]]
 2355             [count(./option)>24]
 2356         /following-sibling::select
 2357             [@id="name_minute"]
 2358             [./option[@value="1"]]
 2359             [count(./option)>59]
 2360     ]
 2361     [count(./select)=2]
 2362 '
 2363         );
 2364     }
 2365 
 2366     public function testTimezone()
 2367     {
 2368         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TimezoneType', 'Europe/Vienna');
 2369 
 2370         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2371 '/select
 2372     [@name="name"]
 2373     [@class="my&class form-control"]
 2374     [not(@required)]
 2375     [.//option[@value="Europe/Vienna"][@selected="selected"]]
 2376     [count(.//option)>200]
 2377 '
 2378         );
 2379     }
 2380 
 2381     public function testTimezoneWithPlaceholder()
 2382     {
 2383         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TimezoneType', null, [
 2384             'placeholder' => 'Select&Timezone',
 2385             'required' => false,
 2386         ]);
 2387 
 2388         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2389 '/select
 2390     [@class="my&class form-control"]
 2391     [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Select&Timezone[/trans]"]]
 2392     [count(.//option)>201]
 2393 '
 2394         );
 2395     }
 2396 
 2397     public function testUrlWithDefaultProtocol()
 2398     {
 2399         $url = 'http://www.example.com?foo1=bar1&foo2=bar2';
 2400         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']);
 2401 
 2402         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2403 '/input
 2404     [@type="text"]
 2405     [@name="name"]
 2406     [@class="my&class form-control"]
 2407     [@value="http://www.example.com?foo1=bar1&foo2=bar2"]
 2408     [@inputmode="url"]
 2409 '
 2410         );
 2411     }
 2412 
 2413     public function testUrlWithoutDefaultProtocol()
 2414     {
 2415         $url = 'http://www.example.com?foo1=bar1&foo2=bar2';
 2416         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]);
 2417 
 2418         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2419             '/input
 2420     [@type="url"]
 2421     [@name="name"]
 2422     [@class="my&class form-control"]
 2423     [@value="http://www.example.com?foo1=bar1&foo2=bar2"]
 2424 '
 2425         );
 2426     }
 2427 
 2428     public function testButton()
 2429     {
 2430         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ButtonType');
 2431 
 2432         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2433             '/button[@type="button"][@name="name"][.="[trans]Name[/trans]"][@class="my&class btn"]'
 2434         );
 2435     }
 2436 
 2437     public function testButtonlabelWithoutTranslation()
 2438     {
 2439         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ButtonType', null, [
 2440             'translation_domain' => false,
 2441         ]);
 2442 
 2443         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2444             '/button[@type="button"][@name="name"][.="Name"][@class="my&class btn"]'
 2445         );
 2446     }
 2447 
 2448     public function testSubmit()
 2449     {
 2450         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\SubmitType');
 2451 
 2452         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2453             '/button[@type="submit"][@name="name"][@class="my&class btn"]'
 2454         );
 2455     }
 2456 
 2457     public function testReset()
 2458     {
 2459         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ResetType');
 2460 
 2461         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2462             '/button[@type="reset"][@name="name"][@class="my&class btn"]'
 2463         );
 2464     }
 2465 
 2466     public function testWidgetAttributes()
 2467     {
 2468         $form = $this->factory->createNamed('text', 'Symfony\Component\Form\Extension\Core\Type\TextType', 'value', [
 2469             'required' => true,
 2470             'disabled' => true,
 2471             'attr' => ['readonly' => true, 'maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'],
 2472         ]);
 2473 
 2474         $html = $this->renderWidget($form->createView());
 2475 
 2476         // compare plain HTML to check the whitespace
 2477         $this->assertSame('<input type="text" id="text" name="text" disabled="disabled" required="required" readonly="readonly" maxlength="10" pattern="\d+" class="foobar form-control" data-foo="bar" value="value" />', $html);
 2478     }
 2479 
 2480     public function testWidgetAttributeNameRepeatedIfTrue()
 2481     {
 2482         $form = $this->factory->createNamed('text', 'Symfony\Component\Form\Extension\Core\Type\TextType', 'value', [
 2483             'attr' => ['foo' => true],
 2484         ]);
 2485 
 2486         $html = $this->renderWidget($form->createView());
 2487 
 2488         // foo="foo"
 2489         $this->assertSame('<input type="text" id="text" name="text" required="required" foo="foo" class="form-control" value="value" />', $html);
 2490     }
 2491 
 2492     public function testButtonAttributes()
 2493     {
 2494         $form = $this->factory->createNamed('button', 'Symfony\Component\Form\Extension\Core\Type\ButtonType', null, [
 2495             'disabled' => true,
 2496             'attr' => ['class' => 'foobar', 'data-foo' => 'bar'],
 2497         ]);
 2498 
 2499         $html = $this->renderWidget($form->createView());
 2500 
 2501         // compare plain HTML to check the whitespace
 2502         $this->assertSame('<button type="button" id="button" name="button" disabled="disabled" class="foobar btn" data-foo="bar">[trans]Button[/trans]</button>', $html);
 2503     }
 2504 
 2505     public function testButtonAttributeNameRepeatedIfTrue()
 2506     {
 2507         $form = $this->factory->createNamed('button', 'Symfony\Component\Form\Extension\Core\Type\ButtonType', null, [
 2508             'attr' => ['foo' => true],
 2509         ]);
 2510 
 2511         $html = $this->renderWidget($form->createView());
 2512 
 2513         // foo="foo"
 2514         $this->assertSame('<button type="button" id="button" name="button" foo="foo" class="btn-default btn">[trans]Button[/trans]</button>', $html);
 2515     }
 2516 
 2517     public function testTel()
 2518     {
 2519         $tel = '0102030405';
 2520         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TelType', $tel);
 2521 
 2522         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2523             '/input
 2524     [@type="tel"]
 2525     [@name="name"]
 2526     [@class="my&class form-control"]
 2527     [@value="0102030405"]
 2528 '
 2529         );
 2530     }
 2531 
 2532     public function testColor()
 2533     {
 2534         $color = '#0000ff';
 2535         $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ColorType', $color);
 2536 
 2537         $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
 2538             '/input
 2539     [@type="color"]
 2540     [@name="name"]
 2541     [@class="my&class form-control"]
 2542     [@value="#0000ff"]
 2543 '
 2544         );
 2545     }
 2546 }