Skip to content
This repository has been archived by the owner on Sep 30, 2021. It is now read-only.

Commit

Permalink
Implemented test suite for widget rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Jun 17, 2016
1 parent 14df1fa commit 3fb5734
Show file tree
Hide file tree
Showing 3 changed files with 241 additions and 0 deletions.
127 changes: 127 additions & 0 deletions Test/Form/Widget/AbstractWidgetTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\CoreBundle\Test\Form\Widget;

use Symfony\Bridge\Twig\Extension\FormExtension;
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Bridge\Twig\Form\TwigRenderer;
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader;
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator;
use Symfony\Component\Form\FormExtensionInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Test\TypeTestCase;

/**
* @author Christian Gripp <mail@core23.de>
*
* Base class for tests checking rendering of form widgets.
*/
abstract class AbstractWidgetTestCase extends TypeTestCase
{
/**
* @var FormExtensionInterface
*/
private $extension;

/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();

$rendererEngine = new TwigRendererEngine(array(
'form_div_layout.html.twig',
));

if (class_exists('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface')) {
$csrfManagerClass = 'Symfony\Component\Security\Csrf\CsrfTokenManagerInterface';
} else {
$csrfManagerClass = 'Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface';
}

$renderer = new TwigRenderer($rendererEngine, $this->getMock($csrfManagerClass));

$this->extension = new FormExtension($renderer);

/*
* this is an workaround for different composer requirements and different TwigBridge installation directories
*/
$twigPaths = array_filter(array(
// symfony/twig-bridge
__DIR__.'/../../../vendor/symfony/twig-bridge/Resources/views/Form',
// symfony/symfony
__DIR__.'/../../../vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form',
), 'is_dir');

$twigPaths[] = __DIR__.'/../../../Resources/views/Form';

$loader = new StubFilesystemLoader($twigPaths);

$environment = new \Twig_Environment($loader, array('strict_variables' => true));
$environment->addExtension(new TranslationExtension(new StubTranslator()));
foreach ($this->getTwigExtensions() as $extension) {
$environment->addExtension($extension);
}
$environment->addExtension($this->extension);

$this->extension->initRuntime($environment);
}

/**
* @return \Twig_ExtensionInterface[]
*/
protected function getTwigExtensions()
{
return array();
}

/**
* Renders widget from FormView, in SonataAdmin context, with optional view variables $vars. Returns plain HTML.
*
* @param FormView $view
* @param array $vars
*
* @return string
*/
final protected function renderWidget(FormView $view, array $vars = array())
{
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'widget', $vars);
}

/**
* Helper method to strip newline and space characters from html string to make comparing easier.
*
* @param string $html
*
* @return string
*/
final protected function cleanHtmlWhitespace($html)
{
return preg_replace_callback('/>([^<]+)</', function ($value) {
return '>'.trim($value[1]).'<';
}, $html);
}

/**
* @param string $html
*
* @return string
*/
final protected function cleanHtmlAttributeWhitespace($html)
{
return preg_replace_callback('~<([A-Z0-9]+) \K(.*?)>~i', function ($m) {
return preg_replace('~\s*~', '', $m[0]);
}, $html);
}
}
113 changes: 113 additions & 0 deletions Tests/Form/Type/FormChoiceWidgetTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php

namespace Sonata\CoreBundle\Tests\Form\Type;

use Sonata\CoreBundle\Test\Form\Widget\AbstractWidgetTestCase;

class FormChoiceWidgetTest extends AbstractWidgetTestCase
{
public function testLabelRendering()
{
$choices = array('some', 'choices');
if (!method_exists('Symfony\Component\Form\FormTypeInterface', 'setDefaultOptions')) {
$choices = array_flip($choices);
}

$choice = $this->factory->create(
$this->getChoiceClass(),
null,
$this->getDefaultOption() + array(
'multiple' => true,
'expanded' => true,
) + compact('choices')
);

$html = $this->renderWidget($choice->createView());

$this->assertContains(
'<li><div class="checkbox"><label><input type="checkbox" id="choice_0" name="choice[]" value="0" /><span class="control-label__text">[trans]some[/trans]</span></label></div></li>',
$this->cleanHtmlWhitespace($html)
);
}

public function testDefaultValueRendering()
{
$choice = $this->factory->create(
$this->getChoiceClass(),
null,
$this->getDefaultOption()
);

$html = $this->renderWidget($choice->createView());

$this->assertContains(
'<option value="" selected="selected">[trans]Choose an option[/trans]</option>',
$this->cleanHtmlWhitespace($html)
);
}

public function testRequiredIsDisabledForEmptyPlaceholder()
{
$choice = $this->factory->create(
$this->getChoiceClass(),
null,
$this->getRequiredOption()
);

$html = $this->renderWidget($choice->createView());

$this->assertNotContains(
'required="required"',
$this->cleanHtmlWhitespace($html)
);
}

public function testRequiredIsEnabledIfPlaceholderIsSet()
{
$choice = $this->factory->create(
$this->getChoiceClass(),
null,
array_merge($this->getRequiredOption(), $this->getDefaultOption())
);

$html = $this->renderWidget($choice->createView());

$this->assertContains(
'required="required"',
$this->cleanHtmlWhitespace($html)
);
}

protected function getRequiredOption()
{
return array('required' => true);
}

protected function getChoiceClass()
{
return
method_exists('Symfony\Component\Form\AbstractType', 'getBlockPrefix') ?
'Symfony\Component\Form\Extension\Core\Type\ChoiceType' :
'choice';
}

/**
* For SF < 2.6, we use 'empty_data' to provide default empty value.
* For SF >= 2.6, we must use 'placeholder' to achieve the same.
*/
protected function getDefaultOption()
{
if (method_exists(
'Symfony\Component\Form\Tests\AbstractLayoutTest',
'testSingleChoiceNonRequiredWithPlaceholder'
)) {
return array(
'placeholder' => 'Choose an option',
);
} else {
return array(
'empty_value' => 'Choose an option',
);
}
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"symfony/form": "^2.3 || ^3.0",
"symfony/config": "^2.3 || ^3.0",
"symfony/translation": "^2.3 || ^3.0",
"symfony/twig-bridge": "^2.3.5 || ^3.0",
"symfony/validator": "^2.3 || ^3.0",
"symfony/property-access": "^2.3 || ^3.0",
"twig/twig": "^1.23",
Expand Down

0 comments on commit 3fb5734

Please sign in to comment.