bug #16351 [WIP] [Form] [TwigBridge] Bootstrap horizontal theme missing tests (pieter2627)

This PR was submitted for the 2.8 branch but it was merged into the 2.7 branch instead (closes #16351).

Discussion
----------

[WIP] [Form] [TwigBridge] Bootstrap horizontal theme missing tests

| Q                     | A
| ------------------ | ---
| Bug fix?           | no
| New feature?   | yes
| BC breaks?      | no
| Deprecations? | no
| Tests pass?     | yes
| Fixed tickets    |
| License            | MIT
| Doc PR            |

The current bootstrap horizontal theme has a limitation where the inputs will always have `col-sm-2` class applied to them and the developer has no way on changing this when he wants larger/smaller labels or wants to target another screen size only. The same applies for the `div` around the `input`.

PR checks if a label's class has a `col-*` class set and then uses it rather than the default so that the developer can change them as is needed. Again the same for the `div` by checking the `group_attr.class`

This is my first contribution to Symfony and from the contribution docs I see that the following is still needed.

### ToDo
- [ ] Create Doc and its PR
- [ ] Edit `CHANGELOG???`

For the Doc it seems best to edit `cookbook/form/form_customization.rst` and add another 'admonition' below the "built-in form themes" section that highlights this capability?

I'm not sure what will go into the CHANGELOG?

Commits
-------

a35d3d4 [WIP] [Form] [TwigBridge] Bootstrap horizontal theme missing tests
This commit is contained in:
Fabien Potencier 2015-11-28 11:44:05 +01:00
commit fdbf1fa5d8
3 changed files with 279 additions and 6 deletions

View File

@ -25,15 +25,13 @@ col-sm-2
{# Rows #}
{% block form_row -%}
{% spaceless %}
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
{{ form_label(form) }}
{{- form_label(form) -}}
<div class="{{ block('form_group_class') }}">
{{ form_widget(form) }}
{{ form_errors(form) }}
{{- form_widget(form) -}}
{{- form_errors(form) -}}
</div>
</div>
{% endspaceless %}
{##}</div>
{%- endblock form_row %}
{% block checkbox_row -%}

View File

@ -0,0 +1,118 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\AbstractBootstrap3HorizontalLayoutTest;
class FormExtensionBootstrap3HorizontalLayoutTest extends AbstractBootstrap3HorizontalLayoutTest
{
/**
* @var FormExtension
*/
protected $extension;
protected $testableFeatures = array(
'choice_attr',
);
protected function setUp()
{
parent::setUp();
$rendererEngine = new TwigRendererEngine(array(
'bootstrap_3_horizontal_layout.html.twig',
'custom_widgets.html.twig',
));
$renderer = new TwigRenderer($rendererEngine, $this->getMock('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface'));
$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);
}
}

View File

@ -0,0 +1,157 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests;
abstract class AbstractBootstrap3HorizontalLayoutTest extends AbstractBootstrap3LayoutTest
{
public function testLabelOnForm()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType');
$view = $form->createView();
$this->renderWidget($view, array('label' => 'foo'));
$html = $this->renderLabel($view);
$this->assertMatchesXpath($html,
'/label
[@class="col-sm-2 control-label required"]
[.="[trans]Name[/trans]"]
'
);
}
public function testLabelDoesNotRenderFieldAttributes()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
$html = $this->renderLabel($form->createView(), null, array(
'attr' => array(
'class' => 'my&class',
),
));
$this->assertMatchesXpath($html,
'/label
[@for="name"]
[@class="col-sm-2 control-label required"]
'
);
}
public function testLabelWithCustomAttributesPassedDirectly()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
$html = $this->renderLabel($form->createView(), null, array(
'label_attr' => array(
'class' => 'my&class',
),
));
$this->assertMatchesXpath($html,
'/label
[@for="name"]
[@class="my&class col-sm-2 control-label required"]
'
);
}
public function testLabelWithCustomTextAndCustomAttributesPassedDirectly()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
$html = $this->renderLabel($form->createView(), 'Custom label', array(
'label_attr' => array(
'class' => 'my&class',
),
));
$this->assertMatchesXpath($html,
'/label
[@for="name"]
[@class="my&class col-sm-2 control-label required"]
[.="[trans]Custom label[/trans]"]
'
);
}
public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', 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 col-sm-2 control-label required"]
[.="[trans]Custom label[/trans]"]
'
);
}
public function testStartTag()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
'method' => 'get',
'action' => 'http://example.com/directory',
));
$html = $this->renderStart($form->createView());
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="form-horizontal">', $html);
}
public function testStartTagWithOverriddenVars()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
'method' => 'put',
'action' => 'http://example.com/directory',
));
$html = $this->renderStart($form->createView(), array(
'method' => 'post',
'action' => 'http://foo.com/directory',
));
$this->assertSame('<form name="form" method="post" action="http://foo.com/directory" class="form-horizontal">', $html);
}
public function testStartTagForMultipartForm()
{
$form = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
'method' => 'get',
'action' => 'http://example.com/directory',
))
->add('file', 'Symfony\Component\Form\Extension\Core\Type\FileType')
->getForm();
$html = $this->renderStart($form->createView());
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="form-horizontal" enctype="multipart/form-data">', $html);
}
public function testStartTagWithExtraAttributes()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
'method' => 'get',
'action' => 'http://example.com/directory',
));
$html = $this->renderStart($form->createView(), array(
'attr' => array('class' => 'foobar'),
));
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="foobar form-horizontal">', $html);
}
}