[Form] Added form debug collector
This commit is contained in:
parent
98c0d38a44
commit
1972a91653
@ -218,6 +218,7 @@ class FrameworkExtension extends Extension
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$loader->load('form_debug.xml');
|
||||||
$loader->load('profiling.xml');
|
$loader->load('profiling.xml');
|
||||||
$loader->load('collectors.xml');
|
$loader->load('collectors.xml');
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
<parameter key="data_collector.time.class">Symfony\Component\HttpKernel\DataCollector\TimeDataCollector</parameter>
|
<parameter key="data_collector.time.class">Symfony\Component\HttpKernel\DataCollector\TimeDataCollector</parameter>
|
||||||
<parameter key="data_collector.memory.class">Symfony\Component\HttpKernel\DataCollector\MemoryDataCollector</parameter>
|
<parameter key="data_collector.memory.class">Symfony\Component\HttpKernel\DataCollector\MemoryDataCollector</parameter>
|
||||||
<parameter key="data_collector.router.class">Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector</parameter>
|
<parameter key="data_collector.router.class">Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector</parameter>
|
||||||
|
<parameter key="data_collector.form.class">Symfony\Component\Form\Extension\DataCollector\Collector\FormCollector</parameter>
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
@ -53,5 +54,10 @@
|
|||||||
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController"/>
|
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController"/>
|
||||||
<tag name="data_collector" template="@WebProfiler/Collector/router.html.twig" id="router" priority="255" />
|
<tag name="data_collector" template="@WebProfiler/Collector/router.html.twig" id="router" priority="255" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="data_collector.form" class="%data_collector.form.class%" >
|
||||||
|
<tag name="data_collector" template="@WebProfiler/Collector/form.html.twig" id="form" priority="255" />
|
||||||
|
</service>
|
||||||
|
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
|
||||||
|
<container xmlns="http://symfony.com/schema/dic/services"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||||
|
|
||||||
|
<parameters>
|
||||||
|
<parameter key="form.type_extension.form.data_collector.class">Symfony\Component\Form\Extension\DataCollector\Type\DataCollectorTypeExtension</parameter>
|
||||||
|
<parameter key="form.type_extension.form.data_collector.event_subscriber.class">Symfony\Component\Form\Extension\DataCollector\EventListener\DataCollectorSubscriber</parameter>
|
||||||
|
</parameters>
|
||||||
|
|
||||||
|
<services>
|
||||||
|
<!-- DataCollectorExtension -->
|
||||||
|
<service id="form.type_extension.form.data_collector" class="%form.type_extension.form.data_collector.class%">
|
||||||
|
<tag name="form.type_extension" alias="form" />
|
||||||
|
<argument type="service" id="form.type_extension.form.data_collector.event_subscriber" />
|
||||||
|
</service>
|
||||||
|
<service id="form.type_extension.form.data_collector.event_subscriber" class="%form.type_extension.form.data_collector.event_subscriber.class%" public="false">
|
||||||
|
<argument type="service" id="data_collector.form" />
|
||||||
|
</service>
|
||||||
|
</services>
|
||||||
|
</container>
|
@ -0,0 +1,56 @@
|
|||||||
|
{% extends app.request.isXmlHttpRequest ? 'WebProfilerBundle:Profiler:ajax_layout.html.twig' : 'WebProfilerBundle:Profiler:layout.html.twig' %}
|
||||||
|
|
||||||
|
{% block toolbar %}
|
||||||
|
{% if collector.dataCount %}
|
||||||
|
{% set icon %}
|
||||||
|
<img width="20" height="28" alt="Forms" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAbCAYAAAB836/YAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpDNkE1RUQ2RjBFMzcxMUUzOEIyQkVBRkQ5QzNENTIxMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpDNkE1RUQ3MDBFMzcxMUUzOEIyQkVBRkQ5QzNENTIxMyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkM2QTVFRDZEMEUzNzExRTM4QjJCRUFGRDlDM0Q1MjEzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkM2QTVFRDZFMEUzNzExRTM4QjJCRUFGRDlDM0Q1MjEzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+fkaAkgAAAQtJREFUeNpi/P//PwM1ARMDlQGLg4MDgsPCAqb//PnDwMzMDGJ+//v3L4oGqDgnSBxZPdwMLJa4ggioQRzoklBxVySh3SguBOICGOffv38TgNQuIny2C6oeRDEim8Fob28PjxVgBIEk/zMyMhIVXqAIZYQo/o81UlhZWcGYWIBNLQta+PACKS1iDYSGJy9OA4Fe+EBKUsKWhlmwpMtZZCS/NHzJ5iFFCRuN7wXEEtQ0sJDirIfGrwBiLiL0HSbWwLPoWQkH2I0tu+KKlOVk+BSngclALEnNMHSldqTMJtOcCFwGNlDbhZ1Y1LwhwpwTuAz0waI4gxIXPqC2lzuoYeAPalajjIO+ogcIMAAaCkonoOPIhQAAAABJRU5ErkJggg=="/>
|
||||||
|
<span class="sf-toolbar-status{% if collector.dataCount %} sf-toolbar-status-red{% endif %}">{{ collector.dataCount }}</span>
|
||||||
|
{% endset %}
|
||||||
|
|
||||||
|
{% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block menu %}
|
||||||
|
<span class="label">
|
||||||
|
<span class="icon"><img src="data:image/png;base64,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" alt=""/></span>
|
||||||
|
<strong>Forms</strong>
|
||||||
|
{% if collector.dataCount %}
|
||||||
|
<span class="count"><span>{{ collector.dataCount }}</span></span>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block panel %}
|
||||||
|
<h2>Invalid Forms</h2>
|
||||||
|
|
||||||
|
{% for formName, fields in collector.data %}
|
||||||
|
<h3>{{ formName }}</h3>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Value</th>
|
||||||
|
<th>Messages</th>
|
||||||
|
</tr>
|
||||||
|
{% for fieldName, field in fields %}
|
||||||
|
<tr>
|
||||||
|
<td><b>{{ fieldName }}</b></td>
|
||||||
|
<td>{{ field.type }}</td>
|
||||||
|
<td>{{ field.value }}</td>
|
||||||
|
<td>
|
||||||
|
<ul>
|
||||||
|
{% for errorMessage in field.errors %}
|
||||||
|
<li>
|
||||||
|
{{ errorMessage.message }}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<em>No invalid form{% if collector.dataCount > 1 %}s{% endif %} detected for this request.</em>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,79 @@
|
|||||||
|
<?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\Extension\DataCollector\Collector;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpKernel\DataCollector\DataCollector as BaseCollector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataCollector for Form Validation Failures.
|
||||||
|
*
|
||||||
|
* @author Robert Schönthal <robert.schoenthal@gmail.com>
|
||||||
|
*/
|
||||||
|
class FormCollector extends BaseCollector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||||
|
{
|
||||||
|
//nothing to do, everything is added with addError()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a Form-Error to the Collector.
|
||||||
|
*
|
||||||
|
* @param FormInterface $form
|
||||||
|
*/
|
||||||
|
public function addError(FormInterface $form)
|
||||||
|
{
|
||||||
|
$storeData = array(
|
||||||
|
'root' => $form->getRoot()->getName(),
|
||||||
|
'name' => (string)$form->getPropertyPath(),
|
||||||
|
'type' => $form->getConfig()->getType()->getName(),
|
||||||
|
'errors' => $form->getErrors(),
|
||||||
|
'value' => $this->varToString($form->getViewData())
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->data[$storeData['root']][$storeData['name']] = $storeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'form';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all collected Data.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of invalid Forms.
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getDataCount()
|
||||||
|
{
|
||||||
|
return count($this->data);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
<?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\Extension\DataCollector;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Form\AbstractExtension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataCollectorExtension for collecting Form Validation Failures.
|
||||||
|
*
|
||||||
|
* @author Robert Schönthal <robert.schoenthal@gmail.com>
|
||||||
|
*/
|
||||||
|
class DataCollectorExtension extends AbstractExtension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var EventSubscriberInterface
|
||||||
|
*/
|
||||||
|
private $eventSubscriber;
|
||||||
|
|
||||||
|
public function __construct(EventSubscriberInterface $eventSubscriber)
|
||||||
|
{
|
||||||
|
$this->eventSubscriber = $eventSubscriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
protected function loadTypeExtensions()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
new Type\DataCollectorTypeExtension($this->eventSubscriber)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
<?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\Extension\DataCollector\EventListener;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Form\Extension\DataCollector\Collector\FormCollector;
|
||||||
|
use Symfony\Component\Form\FormEvent;
|
||||||
|
use Symfony\Component\Form\FormEvents;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventSubscriber for adding Form Validation Failures to the DataCollector.
|
||||||
|
*
|
||||||
|
* @author Robert Schönthal <robert.schoenthal@gmail.com>
|
||||||
|
*/
|
||||||
|
class DataCollectorSubscriber implements EventSubscriberInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var FormCollector
|
||||||
|
*/
|
||||||
|
private $collector;
|
||||||
|
|
||||||
|
public function __construct(FormCollector $collector)
|
||||||
|
{
|
||||||
|
$this->collector = $collector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public static function getSubscribedEvents()
|
||||||
|
{
|
||||||
|
return array(FormEvents::POST_SUBMIT => array('addToProfiler', -255));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for invalid Form-Data and adds them to the Collector.
|
||||||
|
*
|
||||||
|
* @param FormEvent $event The event object
|
||||||
|
*/
|
||||||
|
public function addToProfiler(FormEvent $event)
|
||||||
|
{
|
||||||
|
$form = $event->getForm();
|
||||||
|
|
||||||
|
if ($form->isRoot()) {
|
||||||
|
$this->addErrors($form);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an invalid Form-Element to the Collector.
|
||||||
|
*
|
||||||
|
* @param FormInterface $form
|
||||||
|
*/
|
||||||
|
private function addErrors(FormInterface $form)
|
||||||
|
{
|
||||||
|
if ($form->getErrors()) {
|
||||||
|
$this->collector->addError($form);
|
||||||
|
}
|
||||||
|
|
||||||
|
//recursively add all child errors
|
||||||
|
foreach ($form->all() as $field) {
|
||||||
|
$this->addErrors($field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
<?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\Extension\DataCollector\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataCollector Type Extension for collecting invalid Forms.
|
||||||
|
*
|
||||||
|
* @author Robert Schönthal <robert.schoenthal@gmail.com>
|
||||||
|
*/
|
||||||
|
class DataCollectorTypeExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var EventSubscriberInterface
|
||||||
|
*/
|
||||||
|
private $eventSubscriber;
|
||||||
|
|
||||||
|
public function __construct(EventSubscriberInterface $eventSubscriber)
|
||||||
|
{
|
||||||
|
$this->eventSubscriber = $eventSubscriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->addEventSubscriber($this->eventSubscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getExtendedType()
|
||||||
|
{
|
||||||
|
return 'form';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
<?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\Extension\DataCollector\Collector;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\Extension\DataCollector\Collector\FormCollector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Symfony\Component\Form\Extension\DataCollector\Collector\FormCollector
|
||||||
|
*/
|
||||||
|
class FormCollectorTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testAddError()
|
||||||
|
{
|
||||||
|
$form = $this->getMock('Symfony\Component\Form\Test\FormInterface');
|
||||||
|
|
||||||
|
$type = $this->getMock('Symfony\Component\Form\FormTypeInterface');
|
||||||
|
$type->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('fizz'));
|
||||||
|
|
||||||
|
$config = $this->getMock('Symfony\Component\Form\FormConfigInterface');
|
||||||
|
$config->expects($this->atLeastOnce())->method('getType')->will($this->returnValue($type));
|
||||||
|
|
||||||
|
$form->expects($this->atLeastOnce())->method('getRoot')->will($this->returnSelf());
|
||||||
|
$form->expects($this->atLeastOnce())->method('getPropertyPath')->will($this->returnValue('bar'));
|
||||||
|
$form->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('foo'));
|
||||||
|
$form->expects($this->atLeastOnce())->method('getViewData')->will($this->returnValue('bazz'));
|
||||||
|
$form->expects($this->atLeastOnce())->method('getErrors')->will($this->returnValue(array('foo')));
|
||||||
|
$form->expects($this->atLeastOnce())->method('getConfig')->will($this->returnValue($config));
|
||||||
|
|
||||||
|
|
||||||
|
$c = new FormCollector();
|
||||||
|
$c->addError($form);
|
||||||
|
|
||||||
|
$this->assertInternalType('array', $c->getData());
|
||||||
|
$this->assertEquals(1, $c->getDataCount());
|
||||||
|
$this->assertEquals(array('foo' => array('bar' => array('value' => 'bazz', 'root' => 'foo', 'type' => 'fizz', 'name' => 'bar', 'errors' => array('foo')))), $c->getData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
<?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\Extension\DataCollector;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Form\Extension\DataCollector\DataCollectorExtension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Symfony\Component\Form\Extension\DataCollector\DataCollectorExtension
|
||||||
|
*/
|
||||||
|
class DataCollectorExtensionTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DataCollectorExtension
|
||||||
|
*/
|
||||||
|
private $extension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EventSubscriberInterface
|
||||||
|
*/
|
||||||
|
private $eventSubscriber;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->eventSubscriber = $this->getMock('Symfony\Component\EventDispatcher\EventSubscriberInterface');
|
||||||
|
$this->extension = new DataCollectorExtension($this->eventSubscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoadTypeExtensions()
|
||||||
|
{
|
||||||
|
$typeExtensions = $this->extension->getTypeExtensions('form');
|
||||||
|
|
||||||
|
$this->assertInternalType('array', $typeExtensions);
|
||||||
|
$this->assertCount(1, $typeExtensions);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Extension\DataCollector\Type\DataCollectorTypeExtension', array_shift($typeExtensions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
|||||||
|
<?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\Extension\DataCollector\EventListener;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\Extension\DataCollector\Collector\FormCollector;
|
||||||
|
use Symfony\Component\Form\Extension\DataCollector\EventListener\DataCollectorSubscriber;
|
||||||
|
use Symfony\Component\Form\FormEvent;
|
||||||
|
use Symfony\Component\Form\FormEvents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Symfony\Component\Form\Extension\DataCollector\EventListener\DataCollectorSubscriber
|
||||||
|
*/
|
||||||
|
class DataCollectorSubscriberTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DataCollectorSubscriber
|
||||||
|
*/
|
||||||
|
private $eventSubscriber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FormCollector
|
||||||
|
*/
|
||||||
|
private $collector;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->collector = $this->getMockBuilder('Symfony\Component\Form\Extension\DataCollector\Collector\FormCollector')->setMethods(array('addError'))->getMock();
|
||||||
|
$this->eventSubscriber = new DataCollectorSubscriber($this->collector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSubscribedEvents()
|
||||||
|
{
|
||||||
|
$events = DataCollectorSubscriber::getSubscribedEvents();
|
||||||
|
|
||||||
|
$this->assertInternalType('array', $events);
|
||||||
|
$this->assertEquals(array(FormEvents::POST_SUBMIT => array('addToProfiler', -255)), $events);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddToProfilerWithSubForm()
|
||||||
|
{
|
||||||
|
$form = $this->getMock('Symfony\Component\Form\Test\FormInterface');
|
||||||
|
$form->expects($this->atLeastOnce())->method('isRoot')->will($this->returnValue(false));
|
||||||
|
|
||||||
|
$formEvent = new FormEvent($form, array());
|
||||||
|
|
||||||
|
$this->collector->expects($this->never())->method('addError');
|
||||||
|
$this->eventSubscriber->addToProfiler($formEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddToProfilerWithInValidForm()
|
||||||
|
{
|
||||||
|
$form = $this->getMock('Symfony\Component\Form\Test\FormInterface');
|
||||||
|
$form->expects($this->atLeastOnce())->method('isRoot')->will($this->returnValue(true));
|
||||||
|
$form->expects($this->atLeastOnce())->method('getErrors')->will($this->returnValue(array('foo')));
|
||||||
|
$form->expects($this->once())->method('all')->will($this->returnValue(array()));
|
||||||
|
|
||||||
|
$formEvent = new FormEvent($form, array());
|
||||||
|
|
||||||
|
$this->collector->expects($this->atLeastOnce())->method('addError')->with($form);
|
||||||
|
$this->eventSubscriber->addToProfiler($formEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
<?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\Extension\DataCollector\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Form\Extension\DataCollector\Type\DataCollectorTypeExtension;
|
||||||
|
|
||||||
|
class DataCollectorTypeExtensionTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DataCollectorTypeExtension
|
||||||
|
*/
|
||||||
|
private $extension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EventSubscriberInterface
|
||||||
|
*/
|
||||||
|
private $eventSubscriber;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->eventSubscriber = $this->getMock('Symfony\Component\EventDispatcher\EventSubscriberInterface');
|
||||||
|
$this->extension = new DataCollectorTypeExtension($this->eventSubscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetExtendedType()
|
||||||
|
{
|
||||||
|
$this->assertEquals('form', $this->extension->getExtendedType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuildForm()
|
||||||
|
{
|
||||||
|
$builder = $this->getMock('Symfony\Component\Form\Test\FormBuilderInterface');
|
||||||
|
$builder->expects($this->atLeastOnce())->method('addEventSubscriber')->with($this->eventSubscriber);
|
||||||
|
|
||||||
|
$this->extension->buildForm($builder, array());
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user