diff --git a/.gitignore b/.gitignore index 418cb5f976..f16d739d03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -phpunit.xml +.php_cs.cache +autoload.php composer.lock composer.phar -autoload.php package*.tar packages.json +phpunit.xml /vendor/ diff --git a/.php_cs b/.php_cs index 3e4d9efb34..11d42d1287 100644 --- a/.php_cs +++ b/.php_cs @@ -3,4 +3,26 @@ return Symfony\CS\Config\Config::create() ->setUsingLinter(false) ->setUsingCache(true) + ->finder( + Symfony\CS\Finder\DefaultFinder::create() + ->in(__DIR__) + ->exclude(array( + // directories containing files with content that is autogenerated by `var_export`, which breaks CS in output code + 'src/Symfony/Component/DependencyInjection/Tests/Fixtures', + 'src/Symfony/Component/Routing/Tests/Fixtures/dumper', + // fixture templates + 'src/Symfony/Component/Templating/Tests/Fixtures/templates', + // resource templates + 'src/Symfony/Bundle/FrameworkBundle/Resources/views/Form', + )) + // file content autogenerated by `var_export` + ->notPath('src/Symfony/Component/Translation/Tests/fixtures/resources.php') + // autogenerated xmls + ->notPath('src/Symfony/Component/Console/Tests/Fixtures/application_1.xml') + ->notPath('src/Symfony/Component/Console/Tests/Fixtures/application_2.xml') + // yml + ->notPath('src/Symfony/Component/Yaml/Tests/Fixtures/sfTests.yml') + // test template + ->notPath('src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Custom/_name_entry_label.html.php') + ) ; diff --git a/.travis.yml b/.travis.yml index aa338bbb40..933cca9457 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,8 @@ env: - SYMFONY_DEPRECATIONS_HELPER=weak before_install: + - if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then git fetch origin "refs/pull/$TRAVIS_PULL_REQUEST/merge"; else git fetch origin "$TRAVIS_BRANCH"; fi; + - if [[ "$TRAVIS_COMMIT" != `git rev-parse FETCH_HEAD` ]]; then echo "Pull request or branch commit hash has changed, aborting!"; exit 1; fi; - travis_retry sudo apt-get install parallel - composer self-update - if [[ "$TRAVIS_PHP_VERSION" != *"nightly" ]]; then phpenv config-rm xdebug.ini; fi; diff --git a/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php b/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php index 81316e8fd4..0fde3a675d 100644 --- a/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php @@ -90,19 +90,11 @@ class TranslationExtension extends \Twig_Extension public function trans($message, array $arguments = array(), $domain = null, $locale = null) { - if (null === $domain) { - $domain = 'messages'; - } - return $this->translator->trans($message, $arguments, $domain, $locale); } public function transchoice($message, $count, array $arguments = array(), $domain = null, $locale = null) { - if (null === $domain) { - $domain = 'messages'; - } - return $this->translator->transChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain, $locale); } diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig index 0a144f692c..01fe46dd06 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig @@ -4,7 +4,7 @@ {% block form_widget_simple -%} {% if type is not defined or 'file' != type %} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %} + {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) -%} {% endif %} {{- parent() -}} {%- endblock form_widget_simple %} @@ -42,48 +42,48 @@ {% block datetime_widget -%} {% if widget == 'single_text' %} {{- block('form_widget_simple') -}} - {% else %} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) %} + {% else -%} + {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
- {{ form_errors(form.date) }} - {{ form_errors(form.time) }} - {{ form_widget(form.date, { datetime: true } ) }}  - {{ form_widget(form.time, { datetime: true } ) }} + {{- form_errors(form.date) -}} + {{- form_errors(form.time) -}} + {{- form_widget(form.date, { datetime: true } ) -}} + {{- form_widget(form.time, { datetime: true } ) -}}
- {% endif %} + {%- endif %} {%- endblock datetime_widget %} {% block date_widget -%} {% if widget == 'single_text' %} {{- block('form_widget_simple') -}} - {% else %} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) %} - {% if datetime is not defined or not datetime %} + {% else -%} + {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} + {% if datetime is not defined or not datetime -%}
- {% endif %} - {{ date_pattern|replace({ + {%- endif %} + {{- date_pattern|replace({ '{{ year }}': form_widget(form.year), '{{ month }}': form_widget(form.month), '{{ day }}': form_widget(form.day), - })|raw }} - {% if datetime is not defined or not datetime %} + })|raw -}} + {% if datetime is not defined or not datetime -%}
- {% endif %} + {%- endif -%} {% endif %} {%- endblock date_widget %} {% block time_widget -%} {% if widget == 'single_text' %} {{- block('form_widget_simple') -}} - {% else %} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) %} - {% if datetime is not defined or false == datetime %} + {% else -%} + {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} + {% if datetime is not defined or false == datetime -%}
- {% endif %} - {{ form_widget(form.hour) }}:{{ form_widget(form.minute) }}{% if with_seconds %}:{{ form_widget(form.second) }}{% endif %} - {% if datetime is not defined or false == datetime %} + {%- endif -%} + {{- form_widget(form.hour) }}:{{ form_widget(form.minute) }}{% if with_seconds %}:{{ form_widget(form.second) }}{% endif %} + {% if datetime is not defined or false == datetime -%}
- {% endif %} + {%- endif -%} {% endif %} {%- endblock time_widget %} @@ -93,57 +93,57 @@ {%- endblock %} {% block choice_widget_expanded -%} - {% if '-inline' in label_attr.class|default('') %} + {% if '-inline' in label_attr.class|default('') -%}
- {% for child in form %} - {{ form_widget(child, { + {%- for child in form %} + {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - }) }} - {% endfor %} + }) -}} + {% endfor -%}
- {% else %} + {%- else -%}
- {% for child in form %} - {{ form_widget(child, { + {%- for child in form %} + {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - }) }} - {% endfor %} + }) -}} + {% endfor -%}
- {% endif %} + {%- endif %} {%- endblock choice_widget_expanded %} {% block checkbox_widget -%} - {% set parent_label_class = parent_label_class|default('') %} + {% set parent_label_class = parent_label_class|default('') -%} {% if 'checkbox-inline' in parent_label_class %} - {{ form_label(form, null, { widget: parent() }) }} - {% else %} + {{- form_label(form, null, { widget: parent() }) -}} + {% else -%}
- {{ form_label(form, null, { widget: parent() }) }} + {{- form_label(form, null, { widget: parent() }) -}}
- {% endif %} + {%- endif %} {%- endblock checkbox_widget %} {% block radio_widget -%} - {% set parent_label_class = parent_label_class|default('') %} + {%- set parent_label_class = parent_label_class|default('') -%} {% if 'radio-inline' in parent_label_class %} - {{ form_label(form, null, { widget: parent() }) }} - {% else %} + {{- form_label(form, null, { widget: parent() }) -}} + {% else -%}
- {{ form_label(form, null, { widget: parent() }) }} + {{- form_label(form, null, { widget: parent() }) -}}
- {% endif %} + {%- endif %} {%- endblock radio_widget %} {# Labels #} {% block form_label -%} - {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' control-label')|trim}) %} + {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' control-label')|trim}) -%} {{- parent() -}} {%- endblock form_label %} -{% block choice_label %} +{% block choice_label -%} {# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #} - {% set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) %} + {%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) -%} {{- block('form_label') -}} {% endblock %} @@ -168,8 +168,8 @@ {% set label = name|humanize %} {% endif %} - {{ widget|raw }} - {{ label is not sameas(false) ? label|trans({}, translation_domain) }} + {{- widget|raw -}} + {{- label is not sameas(false) ? label|trans({}, translation_domain) -}} {% endif %} {% endblock checkbox_radio_label %} @@ -178,9 +178,9 @@ {% block form_row -%}
- {{ form_label(form) }} - {{ form_widget(form) }} - {{ form_errors(form) }} + {{- form_label(form) -}} + {{- form_widget(form) -}} + {{- form_errors(form) -}}
{%- endblock form_row %} @@ -192,35 +192,35 @@ {% block choice_row -%} {% set force_error = true %} - {{ block('form_row') }} + {{- block('form_row') }} {%- endblock choice_row %} {% block date_row -%} {% set force_error = true %} - {{ block('form_row') }} + {{- block('form_row') }} {%- endblock date_row %} {% block time_row -%} {% set force_error = true %} - {{ block('form_row') }} + {{- block('form_row') }} {%- endblock time_row %} {% block datetime_row -%} {% set force_error = true %} - {{ block('form_row') }} + {{- block('form_row') }} {%- endblock datetime_row %} {% block checkbox_row -%}
- {{ form_widget(form) }} - {{ form_errors(form) }} + {{- form_widget(form) -}} + {{- form_errors(form) -}}
{%- endblock checkbox_row %} {% block radio_row -%}
- {{ form_widget(form) }} - {{ form_errors(form) }} + {{- form_widget(form) -}} + {{- form_errors(form) -}}
{%- endblock radio_row %} @@ -231,7 +231,7 @@ {% if form.parent %}{% else %}
{% endif %}
    {%- for error in errors -%} -
  • {{ error.message }}
  • +
  • {{ error.message }}
  • {%- endfor -%}
{% if form.parent %}{% else %}
{% endif %} diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3LayoutTest.php new file mode 100644 index 0000000000..84602c657e --- /dev/null +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3LayoutTest.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Twig\Tests\Extension; + +use Symfony\Bridge\Twig\Extension\FormExtension; +use Symfony\Bridge\Twig\Form\TwigRenderer; +use Symfony\Bridge\Twig\Form\TwigRendererEngine; +use Symfony\Bridge\Twig\Extension\TranslationExtension; +use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubTranslator; +use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader; +use Symfony\Component\Form\FormView; +use Symfony\Component\Form\Tests\AbstractBootstrap3LayoutTest; + +class FormExtensionBootstrap3LayoutTest extends AbstractBootstrap3LayoutTest +{ + /** + * @var FormExtension + */ + protected $extension; + + protected function setUp() + { + parent::setUp(); + + $rendererEngine = new TwigRendererEngine(array( + 'bootstrap_3_layout.html.twig', + 'custom_widgets.html.twig', + )); + $renderer = new TwigRenderer($rendererEngine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface')); + + $this->extension = new FormExtension($renderer); + + $loader = new StubFilesystemLoader(array( + __DIR__.'/../../Resources/views/Form', + __DIR__.'/Fixtures/templates/form', + )); + + $environment = new \Twig_Environment($loader, array('strict_variables' => true)); + $environment->addExtension(new TranslationExtension(new StubTranslator())); + $environment->addExtension($this->extension); + + $this->extension->initRuntime($environment); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->extension = null; + } + + protected function renderForm(FormView $view, array $vars = array()) + { + return (string) $this->extension->renderer->renderBlock($view, 'form', $vars); + } + + protected function renderEnctype(FormView $view) + { + return (string) $this->extension->renderer->searchAndRenderBlock($view, 'enctype'); + } + + protected function renderLabel(FormView $view, $label = null, array $vars = array()) + { + if ($label !== null) { + $vars += array('label' => $label); + } + + return (string) $this->extension->renderer->searchAndRenderBlock($view, 'label', $vars); + } + + protected function renderErrors(FormView $view) + { + return (string) $this->extension->renderer->searchAndRenderBlock($view, 'errors'); + } + + protected function renderWidget(FormView $view, array $vars = array()) + { + return (string) $this->extension->renderer->searchAndRenderBlock($view, 'widget', $vars); + } + + protected function renderRow(FormView $view, array $vars = array()) + { + return (string) $this->extension->renderer->searchAndRenderBlock($view, 'row', $vars); + } + + protected function renderRest(FormView $view, array $vars = array()) + { + return (string) $this->extension->renderer->searchAndRenderBlock($view, 'rest', $vars); + } + + protected function renderStart(FormView $view, array $vars = array()) + { + return (string) $this->extension->renderer->renderBlock($view, 'form_start', $vars); + } + + protected function renderEnd(FormView $view, array $vars = array()) + { + return (string) $this->extension->renderer->renderBlock($view, 'form_end', $vars); + } + + protected function setTheme(FormView $view, array $themes) + { + $this->extension->renderer->setTheme($view, $themes); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php index 5afbdeed1c..8060930664 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php @@ -3,7 +3,7 @@ $required = false; endif; ?> block($form, 'widget_attributes', array( - 'required' => $required + 'required' => $required, )) ?> multiple="multiple" > diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php index 68eec540e2..a43f7de475 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "hidden")) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'hidden')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php index 3775a71771..5fceb49a38 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "number")) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'number')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php index 854952f33f..324eb4782c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php index 845fcb25c3..4390687a69 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "password")) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'password')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php index 35b9b0457f..59b29f4cbc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> % +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> % diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php index d91267fedc..4e442f6ef4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "search")) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'search')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php index c2ab28aa04..0ce4ed2ca7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : "url")) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'url')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php index 2167138a1e..04df261863 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php @@ -1,6 +1,6 @@ This template is used for translation message extraction tests trans('single-quoted key') ?> -trans("double-quoted key") ?> +trans('double-quoted key') ?> trans(<<trans( 'single-quoted key with whitespace and nonescaped \$\n\' sequences' ) ?> -trans( <<trans(<< -trans( <<<'EOF' +trans(<<<'EOF' nowdoc key with whitespace and nonescaped \$\n sequences EOF ) ?> diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php index 0d75129fb9..fce2f07580 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php @@ -26,7 +26,7 @@ interface SecurityFactoryInterface /** * Defines the position at which the provider is called. * Possible values: pre_auth, form, http, and remember_me. - * + * * @return string */ public function getPosition(); diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index eda3ed6419..b7c1407c1c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -83,10 +83,10 @@ - + - + @@ -104,7 +104,7 @@ - + diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml index 624b6b1d1d..d2e60b2511 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml @@ -13,13 +13,13 @@ Symfony\Component\Security\Acl\Domain\ObjectIdentityRetrievalStrategy Symfony\Component\Security\Acl\Domain\SecurityIdentityRetrievalStrategy - Symfony\Component\Security\Acl\Domain\DoctrineAclCache - + Symfony\Component\Security\Acl\Domain\AclCollectionCache + Symfony\Component\Security\Acl\Domain\DoctrineAclCache - + @@ -32,7 +32,7 @@ - + diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml index a61d648b0b..9464f00a27 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml @@ -48,7 +48,5 @@ - - diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml index d715355707..a1292375d9 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml @@ -83,7 +83,7 @@ - + @@ -95,7 +95,9 @@ + + @@ -116,7 +118,7 @@ - + @@ -148,8 +150,7 @@ - + abstract="true" /> - + @@ -52,8 +52,7 @@ - + abstract="true" /> diff --git a/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/multipleNs.php b/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/multipleNs.php index 7db8cd3b67..c7cec646f5 100644 --- a/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/multipleNs.php +++ b/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/multipleNs.php @@ -1,4 +1,5 @@ assertFinalizedValueIs('new_value', $test); $test = $this->getTestBuilder() - ->ifNotInArray(array('foo', 'bar', 'value_from_config' )) + ->ifNotInArray(array('foo', 'bar', 'value_from_config')) ->then($this->returnClosure('new_value')) ->end(); $this->assertFinalizedValueIs('new_value', $test); diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 6c206002c7..c2a548607b 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -826,7 +826,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; $bagClass /** - * $class + * $class. * * This class has been auto-generated * by the Symfony Dependency Injection Component. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php index 116d7dfe70..f15771172e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php @@ -10,7 +10,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; /** - * Container + * Container. * * This class has been auto-generated * by the Symfony Dependency Injection Component. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php index 90b59ff4eb..5497a7587a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php @@ -9,7 +9,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; /** - * ProjectServiceContainer + * ProjectServiceContainer. * * This class has been auto-generated * by the Symfony Dependency Injection Component. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php index 2079bee130..a9a1fffff7 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php @@ -9,7 +9,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; /** - * ProjectServiceContainer + * ProjectServiceContainer. * * This class has been auto-generated * by the Symfony Dependency Injection Component. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php index 5a371a048a..6e7823e090 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php @@ -9,7 +9,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; /** - * ProjectServiceContainer + * ProjectServiceContainer. * * This class has been auto-generated * by the Symfony Dependency Injection Component. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php index 1b86dfc3f8..c2c52fe335 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php @@ -9,7 +9,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; /** - * ProjectServiceContainer + * ProjectServiceContainer. * * This class has been auto-generated * by the Symfony Dependency Injection Component. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index 3a079b7915..5977c1c6e7 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -9,7 +9,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; /** - * ProjectServiceContainer + * ProjectServiceContainer. * * This class has been auto-generated * by the Symfony Dependency Injection Component. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index 7c1a49d46f..0f715c31ca 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -9,7 +9,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; /** - * ProjectServiceContainer + * ProjectServiceContainer. * * This class has been auto-generated * by the Symfony Dependency Injection Component. diff --git a/src/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php index 89853a85cb..fdf810bebd 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php @@ -36,7 +36,8 @@ class FilePathsIteratorTest extends RealIteratorTestCase return array( array( $tmpDir, - array( // paths + array( + // paths $tmpDir.DIRECTORY_SEPARATOR.'.git' => $tmpDir.DIRECTORY_SEPARATOR.'.git', $tmpDir.DIRECTORY_SEPARATOR.'test.py' => $tmpDir.DIRECTORY_SEPARATOR.'test.py', $tmpDir.DIRECTORY_SEPARATOR.'foo' => $tmpDir.DIRECTORY_SEPARATOR.'foo', @@ -44,7 +45,8 @@ class FilePathsIteratorTest extends RealIteratorTestCase $tmpDir.DIRECTORY_SEPARATOR.'test.php' => $tmpDir.DIRECTORY_SEPARATOR.'test.php', $tmpDir.DIRECTORY_SEPARATOR.'toto' => $tmpDir.DIRECTORY_SEPARATOR.'toto', ), - array( // subPaths + array( + // subPaths $tmpDir.DIRECTORY_SEPARATOR.'.git' => '', $tmpDir.DIRECTORY_SEPARATOR.'test.py' => '', $tmpDir.DIRECTORY_SEPARATOR.'foo' => '', @@ -52,7 +54,8 @@ class FilePathsIteratorTest extends RealIteratorTestCase $tmpDir.DIRECTORY_SEPARATOR.'test.php' => '', $tmpDir.DIRECTORY_SEPARATOR.'toto' => '', ), - array( // subPathnames + array( + // subPathnames $tmpDir.DIRECTORY_SEPARATOR.'.git' => '.git', $tmpDir.DIRECTORY_SEPARATOR.'test.py' => 'test.py', $tmpDir.DIRECTORY_SEPARATOR.'foo' => 'foo', diff --git a/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php b/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php index 2e7671991c..702b7fe88a 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php @@ -57,7 +57,7 @@ abstract class BaseType extends AbstractType $uniqueBlockPrefix = '_'.$blockName; } - if (!$translationDomain) { + if (null === $translationDomain) { $translationDomain = $view->parent->vars['translation_domain']; } @@ -81,10 +81,6 @@ abstract class BaseType extends AbstractType } $blockPrefixes[] = $uniqueBlockPrefix; - if (!$translationDomain) { - $translationDomain = 'messages'; - } - $view->vars = array_replace($view->vars, array( 'form' => $view, 'id' => $id, diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php new file mode 100644 index 0000000000..b5354e0bd2 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php @@ -0,0 +1,1818 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests; + +use Symfony\Component\Form\FormError; + +abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest +{ + public function testLabelOnForm() + { + $form = $this->factory->createNamed('name', 'date'); + $view = $form->createView(); + $this->renderWidget($view, array('label' => 'foo')); + $html = $this->renderLabel($view); + + $this->assertMatchesXpath($html, +'/label + [@class="control-label required"] + [.="[trans]Name[/trans]"] +' + ); + } + + public function testLabelDoesNotRenderFieldAttributes() + { + $form = $this->factory->createNamed('name', 'text'); + $html = $this->renderLabel($form->createView(), null, array( + 'attr' => array( + 'class' => 'my&class', + ), + )); + + $this->assertMatchesXpath($html, +'/label + [@for="name"] + [@class="control-label required"] +' + ); + } + + public function testLabelWithCustomAttributesPassedDirectly() + { + $form = $this->factory->createNamed('name', 'text'); + $html = $this->renderLabel($form->createView(), null, array( + 'label_attr' => array( + 'class' => 'my&class', + ), + )); + + $this->assertMatchesXpath($html, +'/label + [@for="name"] + [@class="my&class control-label required"] +' + ); + } + + public function testLabelWithCustomTextAndCustomAttributesPassedDirectly() + { + $form = $this->factory->createNamed('name', 'text'); + $html = $this->renderLabel($form->createView(), 'Custom label', array( + 'label_attr' => array( + 'class' => 'my&class', + ), + )); + + $this->assertMatchesXpath($html, +'/label + [@for="name"] + [@class="my&class control-label required"] + [.="[trans]Custom label[/trans]"] +' + ); + } + + public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly() + { + $form = $this->factory->createNamed('name', 'text', null, array( + 'label' => 'Custom label', + )); + $html = $this->renderLabel($form->createView(), null, array( + 'label_attr' => array( + 'class' => 'my&class', + ), + )); + + $this->assertMatchesXpath($html, +'/label + [@for="name"] + [@class="my&class control-label required"] + [.="[trans]Custom label[/trans]"] +' + ); + } + + public function testErrors() + { + $form = $this->factory->createNamed('name', 'text'); + $form->addError(new FormError('[trans]Error 1[/trans]')); + $form->addError(new FormError('[trans]Error 2[/trans]')); + $view = $form->createView(); + $html = $this->renderErrors($view); + + $this->assertMatchesXpath($html, +'/div + [@class="alert alert-danger"] + [ + ./ul + [@class="list-unstyled"] + [ + ./li + [.="[trans]Error 1[/trans]"] + [ + ./span[@class="glyphicon glyphicon-exclamation-sign"] + ] + /following-sibling::li + [.="[trans]Error 2[/trans]"] + [ + ./span[@class="glyphicon glyphicon-exclamation-sign"] + ] + ] + [count(./li)=2] + ] +' + ); + } + + public function testOverrideWidgetBlock() + { + // see custom_widgets.html.twig + $form = $this->factory->createNamed('text_id', 'text'); + $html = $this->renderWidget($form->createView()); + + $this->assertMatchesXpath($html, +'/div + [ + ./input + [@type="text"] + [@id="text_id"] + [@class="form-control"] + ] + [@id="container"] +' + ); + } + + public function testCheckedCheckbox() + { + $form = $this->factory->createNamed('name', 'checkbox', true); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), +'/div + [@class="checkbox"] + [ + ./label + [.="[trans]Name[/trans]"] + [ + ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class"][@checked="checked"][@value="1"] + ] + ] +' + ); + } + + public function testUncheckedCheckbox() + { + $form = $this->factory->createNamed('name', 'checkbox', false); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), +'/div + [@class="checkbox"] + [ + ./label + [.="[trans]Name[/trans]"] + [ + ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class"][not(@checked)] + ] + ] +' + ); + } + + public function testCheckboxWithValue() + { + $form = $this->factory->createNamed('name', 'checkbox', false, array( + 'value' => 'foo&bar', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), +'/div + [@class="checkbox"] + [ + ./label + [.="[trans]Name[/trans]"] + [ + ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class"][@value="foo&bar"] + ] + ] +' + ); + } + + public function testSingleChoice() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [not(@required)] + [ + ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=2] +' + ); + } + + public function testSingleChoiceWithPreferred() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'preferred_choices' => array('&b'), + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('separator' => '-- sep --', 'attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [not(@required)] + [ + ./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + /following-sibling::option[@disabled="disabled"][not(@selected)][.="-- sep --"] + /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + ] + [count(./option)=3] +' + ); + } + + public function testSingleChoiceWithPreferredAndNoSeparator() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'preferred_choices' => array('&b'), + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('separator' => null, 'attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [not(@required)] + [ + ./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + ] + [count(./option)=2] +' + ); + } + + public function testSingleChoiceWithPreferredAndBlankSeparator() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'preferred_choices' => array('&b'), + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('separator' => '', 'attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [not(@required)] + [ + ./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + /following-sibling::option[@disabled="disabled"][not(@selected)][.=""] + /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + ] + [count(./option)=3] +' + ); + } + + public function testChoiceWithOnlyPreferred() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'preferred_choices' => array('&a', '&b'), + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@class="my&class form-control"] + [count(./option)=2] +' + ); + } + + public function testSingleChoiceNonRequired() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'required' => false, + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [not(@required)] + [ + ./option[@value=""][.="[trans][/trans]"] + /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=3] +' + ); + } + + public function testSingleChoiceNonRequiredNoneSelected() + { + $form = $this->factory->createNamed('name', 'choice', null, array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'required' => false, + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [not(@required)] + [ + ./option[@value=""][.="[trans][/trans]"] + /following-sibling::option[@value="&a"][not(@selected)][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=3] +' + ); + } + + public function testSingleChoiceNonRequiredWithPlaceholder() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'multiple' => false, + 'expanded' => false, + 'required' => false, + 'placeholder' => 'Select&Anything&Not&Me', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [not(@required)] + [ + ./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Select&Anything&Not&Me[/trans]"] + /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=3] +' + ); + } + + public function testSingleChoiceRequiredWithPlaceholder() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'required' => true, + 'multiple' => false, + 'expanded' => false, + 'placeholder' => 'Test&Me', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [@required="required"] + [ + ./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Test&Me[/trans]"] + /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=3] +' + ); + } + + public function testSingleChoiceRequiredWithPlaceholderViaView() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'required' => true, + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('placeholder' => '', 'attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [@required="required"] + [ + ./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"] + /following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=3] +' + ); + } + + public function testSingleChoiceGrouped() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array( + 'Group&1' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'Group&2' => array('&c' => 'Choice&C'), + ), + 'multiple' => false, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [./optgroup[@label="[trans]Group&1[/trans]"] + [ + ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=2] + ] + [./optgroup[@label="[trans]Group&2[/trans]"] + [./option[@value="&c"][not(@selected)][.="[trans]Choice&C[/trans]"]] + [count(./option)=1] + ] + [count(./optgroup)=2] +' + ); + } + + public function testMultipleChoice() + { + $form = $this->factory->createNamed('name', 'choice', array('&a'), array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'required' => true, + 'multiple' => true, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name[]"] + [@class="my&class form-control"] + [@required="required"] + [@multiple="multiple"] + [ + ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=2] +' + ); + } + + public function testMultipleChoiceSkipsPlaceholder() + { + $form = $this->factory->createNamed('name', 'choice', array('&a'), array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'multiple' => true, + 'expanded' => false, + 'placeholder' => 'Test&Me', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name[]"] + [@class="my&class form-control"] + [@multiple="multiple"] + [ + ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=2] +' + ); + } + + public function testMultipleChoiceNonRequired() + { + $form = $this->factory->createNamed('name', 'choice', array('&a'), array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'required' => false, + 'multiple' => true, + 'expanded' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name[]"] + [@class="my&class form-control"] + [@multiple="multiple"] + [ + ./option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"] + /following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"] + ] + [count(./option)=2] +' + ); + } + + public function testSingleChoiceExpanded() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'multiple' => false, + 'expanded' => true, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/div + [ + ./div + [@class="radio"] + [ + ./label + [.="[trans]Choice&A[/trans]"] + [ + ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] + ] + ] + /following-sibling::div + [@class="radio"] + [ + ./label + [.="[trans]Choice&B[/trans]"] + [ + ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] + ] + ] + /following-sibling::input[@type="hidden"][@id="name__token"][@class="form-control"] + ] +' + ); + } + + public function testSingleChoiceExpandedWithPlaceholder() + { + $form = $this->factory->createNamed('name', 'choice', '&a', array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), + 'multiple' => false, + 'expanded' => true, + 'placeholder' => 'Test&Me', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/div + [ + ./div + [@class="radio"] + [ + ./label + [.="[trans]Test&Me[/trans]"] + [ + ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)] + ] + ] + /following-sibling::div + [@class="radio"] + [ + ./label + [.="[trans]Choice&A[/trans]"] + [ + ./input[@type="radio"][@name="name"][@id="name_0"][@checked] + ] + ] + /following-sibling::div + [@class="radio"] + [ + ./label + [.="[trans]Choice&B[/trans]"] + [ + ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)] + ] + ] + /following-sibling::input[@type="hidden"][@id="name__token"][@class="form-control"] + ] +' + ); + } + + public function testSingleChoiceExpandedWithBooleanValue() + { + $form = $this->factory->createNamed('name', 'choice', true, array( + 'choices' => array('1' => 'Choice&A', '0' => 'Choice&B'), + 'multiple' => false, + 'expanded' => true, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/div + [ + ./div + [@class="radio"] + [ + ./label + [.="[trans]Choice&A[/trans]"] + [ + ./input[@type="radio"][@name="name"][@id="name_0"][@checked] + ] + ] + /following-sibling::div + [@class="radio"] + [ + ./label + [.="[trans]Choice&B[/trans]"] + [ + ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)] + ] + ] + /following-sibling::input[@type="hidden"][@id="name__token"][@class="form-control"] + ] +' + ); + } + + public function testMultipleChoiceExpanded() + { + $form = $this->factory->createNamed('name', 'choice', array('&a', '&c'), array( + 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B', '&c' => 'Choice&C'), + 'multiple' => true, + 'expanded' => true, + 'required' => true, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/div + [ + ./div + [@class="checkbox"] + [ + ./label + [.="[trans]Choice&A[/trans]"] + [ + ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)] + ] + ] + /following-sibling::div + [@class="checkbox"] + [ + ./label + [.="[trans]Choice&B[/trans]"] + [ + ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)] + ] + ] + /following-sibling::div + [@class="checkbox"] + [ + ./label + [.="[trans]Choice&C[/trans]"] + [ + ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)] + ] + ] + /following-sibling::input[@type="hidden"][@id="name__token"][@class="form-control"] + ] +' + ); + } + + public function testCountry() + { + $form = $this->factory->createNamed('name', 'country', 'AT'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [./option[@value="AT"][@selected="selected"][.="[trans]Austria[/trans]"]] + [count(./option)>200] +' + ); + } + + public function testCountryWithPlaceholder() + { + $form = $this->factory->createNamed('name', 'country', 'AT', array( + 'placeholder' => 'Select&Country', + 'required' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Select&Country[/trans]"]] + [./option[@value="AT"][@selected="selected"][.="[trans]Austria[/trans]"]] + [count(./option)>201] +' + ); + } + + public function testDateTime() + { + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( + 'input' => 'string', + 'with_seconds' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [ + ./select + [@id="name_date_month"] + [@class="form-control"] + [./option[@value="2"][@selected="selected"]] + /following-sibling::select + [@id="name_date_day"] + [@class="form-control"] + [./option[@value="3"][@selected="selected"]] + /following-sibling::select + [@id="name_date_year"] + [@class="form-control"] + [./option[@value="2011"][@selected="selected"]] + /following-sibling::select + [@id="name_time_hour"] + [@class="form-control"] + [./option[@value="4"][@selected="selected"]] + /following-sibling::select + [@id="name_time_minute"] + [@class="form-control"] + [./option[@value="5"][@selected="selected"]] + ] + [count(.//select)=5] +' + ); + } + + public function testDateTimeWithPlaceholderGlobal() + { + $form = $this->factory->createNamed('name', 'datetime', null, array( + 'input' => 'string', + 'placeholder' => 'Change&Me', + 'required' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_date_month"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + /following-sibling::select + [@id="name_date_day"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + /following-sibling::select + [@id="name_date_year"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + /following-sibling::select + [@id="name_time_hour"] + [@class="form-control"] + [./option[@value=""][.="[trans]Change&Me[/trans]"]] + /following-sibling::select + [@id="name_time_minute"] + [@class="form-control"] + [./option[@value=""][.="[trans]Change&Me[/trans]"]] + ] + [count(.//select)=5] +' + ); + } + + public function testDateTimeWithHourAndMinute() + { + $data = array('year' => '2011', 'month' => '2', 'day' => '3', 'hour' => '4', 'minute' => '5'); + + $form = $this->factory->createNamed('name', 'datetime', $data, array( + 'input' => 'array', + 'required' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_date_month"] + [@class="form-control"] + [./option[@value="2"][@selected="selected"]] + /following-sibling::select + [@id="name_date_day"] + [@class="form-control"] + [./option[@value="3"][@selected="selected"]] + /following-sibling::select + [@id="name_date_year"] + [@class="form-control"] + [./option[@value="2011"][@selected="selected"]] + /following-sibling::select + [@id="name_time_hour"] + [@class="form-control"] + [./option[@value="4"][@selected="selected"]] + /following-sibling::select + [@id="name_time_minute"] + [@class="form-control"] + [./option[@value="5"][@selected="selected"]] + ] + [count(.//select)=5] +' + ); + } + + public function testDateTimeWithSeconds() + { + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( + 'input' => 'string', + 'with_seconds' => true, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_date_month"] + [@class="form-control"] + [./option[@value="2"][@selected="selected"]] + /following-sibling::select + [@id="name_date_day"] + [@class="form-control"] + [./option[@value="3"][@selected="selected"]] + /following-sibling::select + [@id="name_date_year"] + [@class="form-control"] + [./option[@value="2011"][@selected="selected"]] + /following-sibling::select + [@id="name_time_hour"] + [@class="form-control"] + [./option[@value="4"][@selected="selected"]] + /following-sibling::select + [@id="name_time_minute"] + [@class="form-control"] + [./option[@value="5"][@selected="selected"]] + /following-sibling::select + [@id="name_time_second"] + [@class="form-control"] + [./option[@value="6"][@selected="selected"]] + ] + [count(.//select)=6] +' + ); + } + + public function testDateTimeSingleText() + { + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( + 'input' => 'string', + 'date_widget' => 'single_text', + 'time_widget' => 'single_text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./input + [@type="date"] + [@id="name_date"] + [@name="name[date]"] + [@class="form-control"] + [@value="2011-02-03"] + /following-sibling::input + [@type="time"] + [@id="name_time"] + [@name="name[time]"] + [@class="form-control"] + [@value="04:05"] + ] +' + ); + } + + public function testDateTimeWithWidgetSingleText() + { + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( + 'input' => 'string', + 'widget' => 'single_text', + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="datetime"] + [@name="name"] + [@class="my&class form-control"] + [@value="2011-02-03T04:05:06Z"] +' + ); + } + + public function testDateTimeWithWidgetSingleTextIgnoreDateAndTimeWidgets() + { + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( + 'input' => 'string', + 'date_widget' => 'choice', + 'time_widget' => 'choice', + 'widget' => 'single_text', + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="datetime"] + [@name="name"] + [@class="my&class form-control"] + [@value="2011-02-03T04:05:06Z"] +' + ); + } + + public function testDateChoice() + { + $form = $this->factory->createNamed('name', 'date', '2011-02-03', array( + 'input' => 'string', + 'widget' => 'choice', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_month"] + [@class="form-control"] + [./option[@value="2"][@selected="selected"]] + /following-sibling::select + [@id="name_day"] + [@class="form-control"] + [./option[@value="3"][@selected="selected"]] + /following-sibling::select + [@id="name_year"] + [@class="form-control"] + [./option[@value="2011"][@selected="selected"]] + ] + [count(./select)=3] +' + ); + } + + public function testDateChoiceWithPlaceholderGlobal() + { + $form = $this->factory->createNamed('name', 'date', null, array( + 'input' => 'string', + 'widget' => 'choice', + 'placeholder' => 'Change&Me', + 'required' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_month"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + /following-sibling::select + [@id="name_day"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + /following-sibling::select + [@id="name_year"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + ] + [count(./select)=3] +' + ); + } + + public function testDateChoiceWithPlaceholderOnYear() + { + $form = $this->factory->createNamed('name', 'date', null, array( + 'input' => 'string', + 'widget' => 'choice', + 'required' => false, + 'placeholder' => array('year' => 'Change&Me'), + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_month"] + [@class="form-control"] + [./option[@value="1"]] + /following-sibling::select + [@id="name_day"] + [@class="form-control"] + [./option[@value="1"]] + /following-sibling::select + [@id="name_year"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + ] + [count(./select)=3] +' + ); + } + + public function testDateText() + { + $form = $this->factory->createNamed('name', 'date', '2011-02-03', array( + 'input' => 'string', + 'widget' => 'text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./input + [@id="name_month"] + [@type="text"] + [@class="form-control"] + [@value="2"] + /following-sibling::input + [@id="name_day"] + [@type="text"] + [@class="form-control"] + [@value="3"] + /following-sibling::input + [@id="name_year"] + [@type="text"] + [@class="form-control"] + [@value="2011"] + ] + [count(./input)=3] +' + ); + } + + public function testDateSingleText() + { + $form = $this->factory->createNamed('name', 'date', '2011-02-03', array( + 'input' => 'string', + 'widget' => 'single_text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="date"] + [@name="name"] + [@class="my&class form-control"] + [@value="2011-02-03"] +' + ); + } + + public function testBirthDay() + { + $form = $this->factory->createNamed('name', 'birthday', '2000-02-03', array( + 'input' => 'string', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_month"] + [@class="form-control"] + [./option[@value="2"][@selected="selected"]] + /following-sibling::select + [@id="name_day"] + [@class="form-control"] + [./option[@value="3"][@selected="selected"]] + /following-sibling::select + [@id="name_year"] + [@class="form-control"] + [./option[@value="2000"][@selected="selected"]] + ] + [count(./select)=3] +' + ); + } + + public function testBirthDayWithPlaceholder() + { + $form = $this->factory->createNamed('name', 'birthday', '1950-01-01', array( + 'input' => 'string', + 'placeholder' => '', + 'required' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_month"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]] + [./option[@value="1"][@selected="selected"]] + /following-sibling::select + [@id="name_day"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]] + [./option[@value="1"][@selected="selected"]] + /following-sibling::select + [@id="name_year"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]] + [./option[@value="1950"][@selected="selected"]] + ] + [count(./select)=3] +' + ); + } + + public function testEmail() + { + $form = $this->factory->createNamed('name', 'email', 'foo&bar'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="email"] + [@name="name"] + [@class="my&class form-control"] + [@value="foo&bar"] + [not(@maxlength)] +' + ); + } + + public function testEmailWithMaxLength() + { + $form = $this->factory->createNamed('name', 'email', 'foo&bar', array( + 'attr' => array('maxlength' => 123), + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="email"] + [@name="name"] + [@class="my&class form-control"] + [@value="foo&bar"] + [@maxlength="123"] +' + ); + } + + public function testHidden() + { + $form = $this->factory->createNamed('name', 'hidden', 'foo&bar'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="hidden"] + [@name="name"] + [@class="my&class form-control"] + [@value="foo&bar"] +' + ); + } + + public function testReadOnly() + { + $form = $this->factory->createNamed('name', 'text', null, array( + 'read_only' => true, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@readonly="readonly"] +' + ); + } + + public function testDisabled() + { + $form = $this->factory->createNamed('name', 'text', null, array( + 'disabled' => true, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@disabled="disabled"] +' + ); + } + + public function testInteger() + { + $form = $this->factory->createNamed('name', 'integer', 123); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="number"] + [@name="name"] + [@class="my&class form-control"] + [@value="123"] +' + ); + } + + public function testLanguage() + { + $form = $this->factory->createNamed('name', 'language', 'de'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [./option[@value="de"][@selected="selected"][.="[trans]German[/trans]"]] + [count(./option)>200] +' + ); + } + + public function testLocale() + { + $form = $this->factory->createNamed('name', 'locale', 'de_AT'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [./option[@value="de_AT"][@selected="selected"][.="[trans]German (Austria)[/trans]"]] + [count(./option)>200] +' + ); + } + + public function testMoney() + { + $form = $this->factory->createNamed('name', 'money', 1234.56, array( + 'currency' => 'EUR', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), +'/div + [@class="input-group"] + [ + ./span + [@class="input-group-addon"] + [contains(.., "€")] + /following-sibling::input + [@id="my&id"] + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@value="1234.56"] + ] +' + ); + } + + public function testNumber() + { + $form = $this->factory->createNamed('name', 'number', 1234.56); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@value="1234.56"] +' + ); + } + + public function testPassword() + { + $form = $this->factory->createNamed('name', 'password', 'foo&bar'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="password"] + [@name="name"] + [@class="my&class form-control"] +' + ); + } + + public function testPasswordSubmittedWithNotAlwaysEmpty() + { + $form = $this->factory->createNamed('name', 'password', null, array( + 'always_empty' => false, + )); + $form->submit('foo&bar'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="password"] + [@name="name"] + [@class="my&class form-control"] + [@value="foo&bar"] +' + ); + } + + public function testPasswordWithMaxLength() + { + $form = $this->factory->createNamed('name', 'password', 'foo&bar', array( + 'attr' => array('maxlength' => 123), + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="password"] + [@name="name"] + [@class="my&class form-control"] + [@maxlength="123"] +' + ); + } + + public function testPercent() + { + $form = $this->factory->createNamed('name', 'percent', 0.1); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), +'/div + [@class="input-group"] + [ + ./input + [@id="my&id"] + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@value="10"] + /following-sibling::span + [@class="input-group-addon"] + [contains(.., "%")] + ] +' + ); + } + + public function testCheckedRadio() + { + $form = $this->factory->createNamed('name', 'radio', true); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), +'/div + [@class="radio"] + [ + ./label + [@class="required"] + [ + ./input + [@id="my&id"] + [@type="radio"] + [@name="name"] + [@class="my&class"] + [@checked="checked"] + [@value="1"] + ] + ] +' + ); + } + + public function testUncheckedRadio() + { + $form = $this->factory->createNamed('name', 'radio', false); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), +'/div + [@class="radio"] + [ + ./label + [@class="required"] + [ + ./input + [@id="my&id"] + [@type="radio"] + [@name="name"] + [@class="my&class"] + [not(@checked)] + ] + ] +' + ); + } + + public function testRadioWithValue() + { + $form = $this->factory->createNamed('name', 'radio', false, array( + 'value' => 'foo&bar', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), +'/div + [@class="radio"] + [ + ./label + [@class="required"] + [ + ./input + [@id="my&id"] + [@type="radio"] + [@name="name"] + [@class="my&class"] + [@value="foo&bar"] + ] + ] +' + ); + } + + public function testTextarea() + { + $form = $this->factory->createNamed('name', 'textarea', 'foo&bar', array( + 'attr' => array('pattern' => 'foo'), + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/textarea + [@name="name"] + [@pattern="foo"] + [@class="my&class form-control"] + [.="foo&bar"] +' + ); + } + + public function testText() + { + $form = $this->factory->createNamed('name', 'text', 'foo&bar'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@value="foo&bar"] + [not(@maxlength)] +' + ); + } + + public function testTextWithMaxLength() + { + $form = $this->factory->createNamed('name', 'text', 'foo&bar', array( + 'attr' => array('maxlength' => 123), + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@value="foo&bar"] + [@maxlength="123"] +' + ); + } + + public function testSearch() + { + $form = $this->factory->createNamed('name', 'search', 'foo&bar'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="search"] + [@name="name"] + [@class="my&class form-control"] + [@value="foo&bar"] + [not(@maxlength)] +' + ); + } + + public function testTime() + { + $form = $this->factory->createNamed('name', 'time', '04:05:06', array( + 'input' => 'string', + 'with_seconds' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_hour"] + [@class="form-control"] + [not(@size)] + [./option[@value="4"][@selected="selected"]] + /following-sibling::select + [@id="name_minute"] + [@class="form-control"] + [not(@size)] + [./option[@value="5"][@selected="selected"]] + ] + [count(./select)=2] +' + ); + } + + public function testTimeWithSeconds() + { + $form = $this->factory->createNamed('name', 'time', '04:05:06', array( + 'input' => 'string', + 'with_seconds' => true, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_hour"] + [@class="form-control"] + [not(@size)] + [./option[@value="4"][@selected="selected"]] + [count(./option)>23] + /following-sibling::select + [@id="name_minute"] + [@class="form-control"] + [not(@size)] + [./option[@value="5"][@selected="selected"]] + [count(./option)>59] + /following-sibling::select + [@id="name_second"] + [@class="form-control"] + [not(@size)] + [./option[@value="6"][@selected="selected"]] + [count(./option)>59] + ] + [count(./select)=3] +' + ); + } + + public function testTimeText() + { + $form = $this->factory->createNamed('name', 'time', '04:05:06', array( + 'input' => 'string', + 'widget' => 'text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./input + [@type="text"] + [@id="name_hour"] + [@name="name[hour]"] + [@class="form-control"] + [@value="04"] + [@required="required"] + [not(@size)] + /following-sibling::input + [@type="text"] + [@id="name_minute"] + [@name="name[minute]"] + [@class="form-control"] + [@value="05"] + [@required="required"] + [not(@size)] + ] + [count(./input)=2] +' + ); + } + + public function testTimeSingleText() + { + $form = $this->factory->createNamed('name', 'time', '04:05:06', array( + 'input' => 'string', + 'widget' => 'single_text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="time"] + [@name="name"] + [@class="my&class form-control"] + [@value="04:05"] + [not(@size)] +' + ); + } + + public function testTimeWithPlaceholderGlobal() + { + $form = $this->factory->createNamed('name', 'time', null, array( + 'input' => 'string', + 'placeholder' => 'Change&Me', + 'required' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_hour"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + [count(./option)>24] + /following-sibling::select + [@id="name_minute"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + [count(./option)>60] + ] + [count(./select)=2] +' + ); + } + + public function testTimeWithPlaceholderOnYear() + { + $form = $this->factory->createNamed('name', 'time', null, array( + 'input' => 'string', + 'required' => false, + 'placeholder' => array('hour' => 'Change&Me'), + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/div + [@class="my&class form-inline"] + [ + ./select + [@id="name_hour"] + [@class="form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Change&Me[/trans]"]] + [count(./option)>24] + /following-sibling::select + [@id="name_minute"] + [./option[@value="1"]] + [count(./option)>59] + ] + [count(./select)=2] +' + ); + } + + public function testTimezone() + { + $form = $this->factory->createNamed('name', 'timezone', 'Europe/Vienna'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@name="name"] + [@class="my&class form-control"] + [not(@required)] + [./optgroup + [@label="[trans]Europe[/trans]"] + [./option[@value="Europe/Vienna"][@selected="selected"][.="[trans]Vienna[/trans]"]] + ] + [count(./optgroup)>10] + [count(.//option)>200] +' + ); + } + + public function testTimezoneWithPlaceholder() + { + $form = $this->factory->createNamed('name', 'timezone', null, array( + 'placeholder' => 'Select&Timezone', + 'required' => false, + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/select + [@class="my&class form-control"] + [./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Select&Timezone[/trans]"]] + [count(./optgroup)>10] + [count(.//option)>201] +' + ); + } + + public function testUrl() + { + $url = 'http://www.google.com?foo1=bar1&foo2=bar2'; + $form = $this->factory->createNamed('name', 'url', $url); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), +'/input + [@type="url"] + [@name="name"] + [@class="my&class form-control"] + [@value="http://www.google.com?foo1=bar1&foo2=bar2"] +' + ); + } + + public function testButton() + { + $form = $this->factory->createNamed('name', 'button'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), + '/button[@type="button"][@name="name"][.="[trans]Name[/trans]"][@class="my&class btn"]' + ); + } + + public function testSubmit() + { + $form = $this->factory->createNamed('name', 'submit'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), + '/button[@type="submit"][@name="name"][@class="my&class btn"]' + ); + } + + public function testReset() + { + $form = $this->factory->createNamed('name', 'reset'); + + $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')), + '/button[@type="reset"][@name="name"][@class="my&class btn"]' + ); + } + + public function testWidgetAttributes() + { + $form = $this->factory->createNamed('text', 'text', 'value', array( + 'required' => true, + 'disabled' => true, + 'read_only' => true, + 'attr' => array('maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'), + )); + + $html = $this->renderWidget($form->createView()); + + // compare plain HTML to check the whitespace + $this->assertSame('', $html); + } + + public function testWidgetAttributeNameRepeatedIfTrue() + { + $form = $this->factory->createNamed('text', 'text', 'value', array( + 'attr' => array('foo' => true), + )); + + $html = $this->renderWidget($form->createView()); + + // foo="foo" + $this->assertSame('', $html); + } + + public function testButtonAttributes() + { + $form = $this->factory->createNamed('button', 'button', null, array( + 'disabled' => true, + 'attr' => array('class' => 'foobar', 'data-foo' => 'bar'), + )); + + $html = $this->renderWidget($form->createView()); + + // compare plain HTML to check the whitespace + $this->assertSame('', $html); + } + + public function testButtonAttributeNameRepeatedIfTrue() + { + $form = $this->factory->createNamed('button', 'button', null, array( + 'attr' => array('foo' => true), + )); + + $html = $this->renderWidget($form->createView()); + + // foo="foo" + $this->assertSame('', $html); + } +} diff --git a/src/Symfony/Component/Form/Tests/AbstractFormTest.php b/src/Symfony/Component/Form/Tests/AbstractFormTest.php index eb580c0f65..dc590c918c 100644 --- a/src/Symfony/Component/Form/Tests/AbstractFormTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractFormTest.php @@ -1,13 +1,13 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ namespace Symfony\Component\Form\Tests; diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index 85f66a1c3f..6375542b28 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -92,9 +92,15 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg 'attr' => array('class' => 'my&class'), ), $vars)); - $xpath = trim($xpath).' - [@id="my&id"] + if (!isset($vars['id'])) { + $xpath = trim($xpath).' + [@id="my&id"]'; + } + + if (!isset($vars['attr']['class'])) { + $xpath .= ' [@class="my&class"]'; + } $this->assertMatchesXpath($html, $xpath); } diff --git a/src/Symfony/Component/Form/Tests/CallbackTransformerTest.php b/src/Symfony/Component/Form/Tests/CallbackTransformerTest.php index 7f3b074e78..af49e69e6c 100644 --- a/src/Symfony/Component/Form/Tests/CallbackTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/CallbackTransformerTest.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Form\Tests; use Symfony\Component\Form\CallbackTransformer; @@ -30,8 +39,8 @@ class CallbackTransformerTest extends \PHPUnit_Framework_TestCase public function invalidCallbacksProvider() { return array( - array( null, function () {} ), - array( function () {}, null ), + array(null, function () {}), + array(function () {}, null), ); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/BaseTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/BaseTypeTest.php index bfa1e21805..0048cf41c5 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/BaseTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/BaseTypeTest.php @@ -112,7 +112,7 @@ abstract class BaseTypeTest extends \Symfony\Component\Form\Test\TypeTestCase ->getForm() ->createView(); - $this->assertEquals('messages', $view['child']->vars['translation_domain']); + $this->assertNull($view['child']->vars['translation_domain']); } public function testPassLabelToView() diff --git a/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php index d431ee8721..f19a8da239 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php @@ -212,13 +212,13 @@ class ParameterBagTest extends \PHPUnit_Framework_TestCase $this->assertFalse($bag->filter('dec', '', false, FILTER_VALIDATE_INT, array( 'flags' => FILTER_FLAG_ALLOW_HEX, - 'options' => array('min_range' => 1, 'max_range' => 0xff)) - ), '->filter() gets a value of parameter as integer between boundaries'); + 'options' => array('min_range' => 1, 'max_range' => 0xff), + )), '->filter() gets a value of parameter as integer between boundaries'); $this->assertFalse($bag->filter('hex', '', false, FILTER_VALIDATE_INT, array( 'flags' => FILTER_FLAG_ALLOW_HEX, - 'options' => array('min_range' => 1, 'max_range' => 0xff)) - ), '->filter() gets a value of parameter as integer between boundaries'); + 'options' => array('min_range' => 1, 'max_range' => 0xff), + )), '->filter() gets a value of parameter as integer between boundaries'); $this->assertEquals(array('bang'), $bag->filter('array', '', false), '->filter() gets a value of parameter as an array'); } diff --git a/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php b/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php index 4049ec4e68..8dc0a7d764 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php @@ -1,4 +1,5 @@ generateCookieHash($class, $username, $expires, $user->getPassword()))) { + if (true !== StringUtils::equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) { throw new AuthenticationException('The cookie\'s hash is invalid.'); }