Merge branch '4.2'

* 4.2:
  New extensions were released supporting PHP 7.3
  Remove "internal" annotation from datacollector serialization methods
  replace mocks with real objects in tests
  [DependencyInjection] fix #29930 add $lazyLoad flag to the generated factory code for lazy non-shared services
  escape function does not always take a string
  Fix phpunit 8 compatibility
  render integer types with grouping as text input
  ignore _method forms in NativeRequestHandler
  don't lose int precision with not needed type casts
This commit is contained in:
Nicolas Grekas 2019-02-08 14:07:06 +01:00
commit 41cc6d2676
40 changed files with 698 additions and 517 deletions

View File

@ -13,7 +13,6 @@ addons:
- slapd
- zookeeperd
- libzookeeper-mt-dev
- libsasl2-dev
env:
global:
@ -50,6 +49,7 @@ before_install:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6B05F25D762E3157
sudo add-apt-repository -y ppa:ondrej/php
sudo apt update
sudo apt install -y librabbitmq-dev libsodium-dev
- |
# Start Redis cluster
@ -153,8 +153,6 @@ before_install:
phpenv global $PHP
INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini
if ! php --ri sodium > /dev/null; then
# install libsodium
sudo apt-get install libsodium-dev -y
tfold ext.libsodium tpecl libsodium sodium.so $INI
fi
@ -162,23 +160,7 @@ before_install:
tfold ext.mongodb tpecl mongodb-1.6.0alpha1 mongodb.so $INI
tfold ext.igbinary tpecl igbinary-2.0.8 igbinary.so $INI
tfold ext.zookeeper tpecl zookeeper-0.6.0 zookeeper.so $INI
if [[ $PHP != 7.3 ]]; then
wget http://ftp.debian.org/debian/pool/main/libr/librabbitmq/librabbitmq-dev_0.5.2-2_amd64.deb
wget http://ftp.debian.org/debian/pool/main/libr/librabbitmq/librabbitmq1_0.5.2-2_amd64.deb
sudo dpkg -i librabbitmq1_0.5.2-2_amd64.deb librabbitmq-dev_0.5.2-2_amd64.deb
tfold ext.amqp tpecl amqp-1.9.3 amqp.so $INI
else
sudo apt install -y librabbitmq-dev
git clone https://github.com/pdezwart/php-amqp.git
cd php-amqp
phpize
./configure
make
sudo make install
cd -
echo extension = amqp.so >> $INI
fi
tfold ext.amqp tpecl amqp-1.9.4 amqp.so $INI
done
- |

View File

@ -1986,6 +1986,22 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
);
}
public function testIntegerTypeWithGroupingRendersAsTextInput()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\IntegerType', 123, [
'grouping' => true,
]);
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
'/input
[@type="text"]
[@name="name"]
[@class="my&class form-control"]
[@value="123"]
'
);
}
public function testLanguage()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\LanguageType', 'de');

View File

@ -112,6 +112,8 @@ abstract class KernelTestCase extends TestCase
}
/**
* @after
*
* Shuts the kernel down if it was used in the test.
*/
protected static function ensureKernelShutdown()
@ -125,12 +127,4 @@ abstract class KernelTestCase extends TestCase
}
static::$container = null;
}
/**
* Clean up Kernel usage in this test.
*/
protected function tearDown()
{
static::ensureKernelShutdown();
}
}

View File

@ -688,8 +688,8 @@ EOF;
$code .= $this->addServiceInclude($id, $definition);
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
$factoryCode = $asFile ? "\$this->load('%s.php', false)" : '$this->%s(false)';
$code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName));
$factoryCode = $asFile ? ($definition->isShared() ? "\$this->load('%s.php', false)" : "\$this->factories['%2$s'](false)") : '$this->%s(false)';
$code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->export($id)));
}
if ($definition->isDeprecated()) {
@ -863,7 +863,9 @@ EOTXT
}
$code[1] = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $code[1])));
$factory = sprintf('$this->factories%s[\'%s\']', $definition->isPublic() ? '' : "['service_container']", $id);
$code[1] = sprintf("%s = function () {\n%s};\n\nreturn %1\$s();\n", $factory, $code[1]);
$lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : '';
$code[1] = sprintf("%s = function (%s) {\n%s};\n\nreturn %1\$s();\n", $factory, $lazyloadInitialization, $code[1]);
$code = $code[0].$code[1];
}

View File

@ -230,6 +230,24 @@ class PhpDumperTest extends TestCase
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump);
}
public function testNonSharedLazyDumpAsFiles()
{
$container = include self::$fixturesPath.'/containers/container_non_shared_lazy.php';
$container->register('non_shared_foo', \Bar\FooLazyClass::class)
->setFile(realpath(self::$fixturesPath.'/includes/foo_lazy.php'))
->setShared(false)
->setPublic(true)
->setLazy(true);
$container->compile();
$dumper = new PhpDumper($container);
$dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__]), true);
if ('\\' === \DIRECTORY_SEPARATOR) {
$dump = str_replace('\\\\Fixtures\\\\includes\\\\foo_lazy.php', '/Fixtures/includes/foo_lazy.php', $dump);
}
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services_non_shared_lazy_as_files.txt', $dump);
}
public function testServicesWithAnonymousFactories()
{
$container = include self::$fixturesPath.'/containers/container19.php';

View File

@ -0,0 +1,5 @@
<?php
use Symfony\Component\DependencyInjection\ContainerBuilder;
return new ContainerBuilder();

View File

@ -0,0 +1,7 @@
<?php
namespace Bar;
class FooLazyClass
{
}

View File

@ -0,0 +1,110 @@
Array
(
[Container%s/removed-ids.php] => <?php
return [
'Psr\\Container\\ContainerInterface' => true,
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
];
[Container%s/getNonSharedFooService.php] => <?php
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the public 'non_shared_foo' service.
include_once ($this->targetDirs[0].'/Fixtures/includes/foo_lazy.php');
$this->factories['non_shared_foo'] = function ($lazyLoad = true) {
return new \Bar\FooLazyClass();
};
return $this->factories['non_shared_foo']();
[Container%s/ProjectServiceContainer.php] => <?php
namespace Container%s;
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
/**
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*
* @final since Symfony 3.3
*/
class ProjectServiceContainer extends Container
{
private $buildParameters;
private $containerDir;
private $parameters;
private $targetDirs = [];
public function __construct(array $buildParameters = [], $containerDir = __DIR__)
{
$dir = $this->targetDirs[0] = \dirname($containerDir);
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->buildParameters = $buildParameters;
$this->containerDir = $containerDir;
$this->services = $this->privates = [];
$this->fileMap = [
'non_shared_foo' => 'getNonSharedFooService.php',
];
$this->aliases = [];
}
public function compile()
{
throw new LogicException('You cannot compile a dumped container that was already compiled.');
}
public function isCompiled()
{
return true;
}
public function getRemovedIds()
{
return require $this->containerDir.\DIRECTORY_SEPARATOR.'removed-ids.php';
}
protected function load($file, $lazyLoad = true)
{
return require $this->containerDir.\DIRECTORY_SEPARATOR.$file;
}
}
[ProjectServiceContainer.php] => <?php
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
if (\class_exists(\Container%s\ProjectServiceContainer::class, false)) {
// no-op
} elseif (!include __DIR__.'/Container%s/ProjectServiceContainer.php') {
touch(__DIR__.'/Container%s.legacy');
return;
}
if (!\class_exists(ProjectServiceContainer::class, false)) {
\class_alias(\Container%s\ProjectServiceContainer::class, ProjectServiceContainer::class, false);
}
return new \Container%s\ProjectServiceContainer([
'container.build_hash' => '%s',
'container.build_id' => '%s',
'container.build_time' => %d,
], __DIR__.\DIRECTORY_SEPARATOR.'Container%s');
)

View File

@ -46,4 +46,12 @@ class IntegerToLocalizedStringTransformer extends NumberToLocalizedStringTransfo
return null !== $result ? (int) $result : null;
}
/**
* @internal
*/
protected function castParsedValue($value)
{
return $value;
}
}

View File

@ -181,9 +181,7 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
throw new TransformationFailedException('I don\'t have a clear idea what infinity looks like');
}
if (\is_int($result) && $result === (int) $float = (float) $result) {
$result = $float;
}
$result = $this->castParsedValue($result);
if (false !== $encoding = mb_detect_encoding($value, null, true)) {
$length = mb_strlen($value, $encoding);
@ -228,6 +226,18 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
return $formatter;
}
/**
* @internal
*/
protected function castParsedValue($value)
{
if (\is_int($value) && $value === (int) $float = (float) $value) {
return $float;
}
return $value;
}
/**
* Rounds a number according to the configured scale and rounding mode.
*

View File

@ -14,6 +14,8 @@ namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\DataTransformer\IntegerToLocalizedStringTransformer;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class IntegerType extends AbstractType
@ -26,6 +28,16 @@ class IntegerType extends AbstractType
$builder->addViewTransformer(new IntegerToLocalizedStringTransformer($options['grouping'], $options['rounding_mode']));
}
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
if ($options['grouping']) {
$view->vars['type'] = 'text';
}
}
/**
* {@inheritdoc}
*/

View File

@ -229,9 +229,6 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
return $this->data;
}
/**
* @internal
*/
public function serialize()
{
foreach ($this->data['forms_by_hash'] as &$form) {

View File

@ -115,6 +115,10 @@ class NativeRequestHandler implements RequestHandlerInterface
return;
}
if (\is_array($data) && array_key_exists('_method', $data) && $method === $data['_method'] && !$form->has('_method')) {
unset($data['_method']);
}
$form->submit($data, 'PATCH' !== $method);
}

View File

@ -1799,6 +1799,21 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
);
}
public function testIntegerTypeWithGroupingRendersAsTextInput()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\IntegerType', 123, [
'grouping' => true,
]);
$this->assertWidgetMatchesXpath($form->createView(), [],
'/input
[@type="text"]
[@name="name"]
[@value="123"]
'
);
}
public function testLanguage()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\LanguageType', 'de');

View File

@ -200,7 +200,7 @@ abstract class AbstractRequestHandlerTest extends TestCase
$form = $this->createForm('param1', $method, true);
$form->add($this->createForm('field1'));
$form->add($this->createBuilder('field2', false, ['allow_file_upload' => true])->getForm());
$file = $this->getMockFile();
$file = $this->getUploadedFile();
$this->setRequestData($method, [
'param1' => [
@ -225,7 +225,7 @@ abstract class AbstractRequestHandlerTest extends TestCase
public function testParamTakesPrecedenceOverFile($method)
{
$form = $this->createForm('param1', $method);
$file = $this->getMockFile();
$file = $this->getUploadedFile();
$this->setRequestData($method, [
'param1' => 'DATA',
@ -247,7 +247,7 @@ abstract class AbstractRequestHandlerTest extends TestCase
$form = $this->createBuilder('param1', false, ['allow_file_upload' => true])
->setMethod($method)
->getForm();
$file = $this->getMockFile();
$file = $this->getUploadedFile();
$this->setRequestData($method, [
'param1' => null,
@ -269,14 +269,14 @@ abstract class AbstractRequestHandlerTest extends TestCase
$form = $this->createBuilder('param1', false, ['allow_file_upload' => true])
->setMethod($method)
->getForm();
$file = $this->getMockFile();
$file = $this->getUploadedFile();
$this->setRequestData($method, [
'param1' => null,
], [
'param2' => $this->getMockFile('2'),
'param2' => $this->getUploadedFile('2'),
'param1' => $file,
'param3' => $this->getMockFile('3'),
'param3' => $this->getUploadedFile('3'),
]);
$this->requestHandler->handleRequest($form, $this->request);
@ -332,7 +332,7 @@ abstract class AbstractRequestHandlerTest extends TestCase
public function testUploadedFilesAreAccepted()
{
$this->assertTrue($this->requestHandler->isFileUpload($this->getMockFile()));
$this->assertTrue($this->requestHandler->isFileUpload($this->getUploadedFile()));
}
public function testInvalidFilesAreRejected()
@ -344,7 +344,7 @@ abstract class AbstractRequestHandlerTest extends TestCase
abstract protected function getRequestHandler();
abstract protected function getMockFile($suffix = '');
abstract protected function getUploadedFile($suffix = '');
abstract protected function getInvalidFile();

View File

@ -20,8 +20,9 @@ use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Command\DebugCommand;
use Symfony\Component\Form\DependencyInjection\FormPass;
use Symfony\Component\Form\FormRegistryInterface;
use Symfony\Component\Form\FormRegistry;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
@ -71,8 +72,12 @@ class FormPassTest extends TestCase
{
$container = $this->createContainerBuilder();
$container->register('form.registry', FormRegistry::class);
$commandDefinition = new Definition(DebugCommand::class, [new Reference('form.registry')]);
$commandDefinition->setPublic(true);
$container->setDefinition('form.extension', $this->createExtensionDefinition());
$container->setDefinition('console.command.form_debug', $this->createDebugCommandDefinition());
$container->setDefinition('console.command.form_debug', $commandDefinition);
$container->register('my.type1', __CLASS__.'_Type1')->addTag('form.type')->setPublic(true);
$container->register('my.type2', __CLASS__.'_Type2')->addTag('form.type')->setPublic(true);
@ -379,19 +384,6 @@ class FormPassTest extends TestCase
return $definition;
}
private function createDebugCommandDefinition()
{
$definition = new Definition('Symfony\Component\Form\Command\DebugCommand');
$definition->setPublic(true);
$definition->setArguments([
$formRegistry = $this->getMockBuilder(FormRegistryInterface::class)->getMock(),
[],
['Symfony\Component\Form\Extension\Core\Type'],
]);
return $definition;
}
private function createContainerBuilder()
{
$container = new ContainerBuilder();

View File

@ -12,9 +12,14 @@
namespace Symfony\Component\Form\Tests\Extension\Core\DataMapper;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigBuilder;
use Symfony\Component\Form\FormConfigInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\PropertyAccess\PropertyPath;
class PropertyPathMapperTest extends TestCase
{
@ -24,74 +29,36 @@ class PropertyPathMapperTest extends TestCase
private $mapper;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var EventDispatcherInterface
*/
private $dispatcher;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var PropertyAccessorInterface
*/
private $propertyAccessor;
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->propertyAccessor = $this->getMockBuilder('Symfony\Component\PropertyAccess\PropertyAccessorInterface')->getMock();
$this->dispatcher = new EventDispatcher();
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
$this->mapper = new PropertyPathMapper($this->propertyAccessor);
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
private function getPropertyPath($path)
{
return $this->getMockBuilder('Symfony\Component\PropertyAccess\PropertyPath')
->setConstructorArgs([$path])
->setMethods(['getValue', 'setValue'])
->getMock();
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
private function getForm(FormConfigInterface $config, bool $synchronized = true, bool $submitted = true)
{
$form = $this->getMockBuilder('Symfony\Component\Form\Form')
->setConstructorArgs([$config])
->setMethods(['isSynchronized', 'isSubmitted'])
->getMock();
$form->expects($this->any())
->method('isSynchronized')
->will($this->returnValue($synchronized));
$form->expects($this->any())
->method('isSubmitted')
->will($this->returnValue($submitted));
return $form;
}
public function testMapDataToFormsPassesObjectRefIfByReference()
{
$car = new \stdClass();
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->once())
->method('getValue')
->with($car, $propertyPath)
->will($this->returnValue($engine));
$car->engine = $engine;
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$form = $this->getForm($config);
$form = new Form($config);
$this->mapper->mapDataToForms($car, [$form]);
// Can't use isIdentical() above because mocks always clone their
// arguments which can't be disabled in PHPUnit 3.6
$this->assertSame($engine, $form->getData());
}
@ -99,17 +66,14 @@ class PropertyPathMapperTest extends TestCase
{
$car = new \stdClass();
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->once())
->method('getValue')
->with($car, $propertyPath)
->will($this->returnValue($engine));
$engine->brand = 'Rolls-Royce';
$car->engine = $engine;
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(false);
$config->setPropertyPath($propertyPath);
$form = $this->getForm($config);
$form = new Form($config);
$this->mapper->mapDataToForms($car, [$form]);
@ -123,7 +87,7 @@ class PropertyPathMapperTest extends TestCase
$config = new FormConfigBuilder(null, '\stdClass', $this->dispatcher);
$config->setByReference(true);
$form = $this->getForm($config);
$form = new Form($config);
$this->assertNull($form->getPropertyPath());
@ -135,16 +99,14 @@ class PropertyPathMapperTest extends TestCase
public function testMapDataToFormsIgnoresUnmapped()
{
$car = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('getValue');
$car->engine = new \stdClass();
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setMapped(false);
$config->setPropertyPath($propertyPath);
$form = $this->getForm($config);
$form = new Form($config);
$this->mapper->mapDataToForms($car, [$form]);
@ -154,204 +116,188 @@ class PropertyPathMapperTest extends TestCase
public function testMapDataToFormsSetsDefaultDataIfPassedDataIsNull()
{
$default = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('getValue');
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($default);
$form = $this->getMockBuilder('Symfony\Component\Form\Form')
->setConstructorArgs([$config])
->setMethods(['setData'])
->getMock();
$form->expects($this->once())
->method('setData')
->with($default);
$form = new Form($config);
$this->mapper->mapDataToForms(null, [$form]);
$this->assertSame($default, $form->getData());
}
public function testMapDataToFormsSetsDefaultDataIfPassedDataIsEmptyArray()
{
$default = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('getValue');
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($default);
$form = $this->getMockBuilder('Symfony\Component\Form\Form')
->setConstructorArgs([$config])
->setMethods(['setData'])
->getMock();
$form->expects($this->once())
->method('setData')
->with($default);
$form = new Form($config);
$this->mapper->mapDataToForms([], [$form]);
$this->assertSame($default, $form->getData());
}
public function testMapFormsToDataWritesBackIfNotByReference()
{
$car = new \stdClass();
$car->engine = new \stdClass();
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->once())
->method('setValue')
->with($car, $propertyPath, $engine);
$engine->brand = 'Rolls-Royce';
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(false);
$config->setPropertyPath($propertyPath);
$config->setData($engine);
$form = $this->getForm($config);
$form = new SubmittedForm($config);
$this->mapper->mapFormsToData([$form], $car);
$this->assertEquals($engine, $car->engine);
$this->assertNotSame($engine, $car->engine);
}
public function testMapFormsToDataWritesBackIfByReferenceButNoReference()
{
$car = new \stdClass();
$car->engine = new \stdClass();
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->once())
->method('setValue')
->with($car, $propertyPath, $engine);
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($engine);
$form = $this->getForm($config);
$form = new SubmittedForm($config);
$this->mapper->mapFormsToData([$form], $car);
$this->assertSame($engine, $car->engine);
}
public function testMapFormsToDataWritesBackIfByReferenceAndReference()
{
$car = new \stdClass();
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$car->engine = 'BMW';
$propertyPath = new PropertyPath('engine');
// $car already contains the reference of $engine
$this->propertyAccessor->expects($this->once())
->method('getValue')
->with($car, $propertyPath)
->will($this->returnValue($engine));
$this->propertyAccessor->expects($this->never())
->method('setValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config = new FormConfigBuilder('engine', null, $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($engine);
$form = $this->getForm($config);
$config->setData('Rolls-Royce');
$form = new SubmittedForm($config);
$car->engine = 'Rolls-Royce';
$this->mapper->mapFormsToData([$form], $car);
$this->assertSame('Rolls-Royce', $car->engine);
}
public function testMapFormsToDataIgnoresUnmapped()
{
$initialEngine = new \stdClass();
$car = new \stdClass();
$car->engine = $initialEngine;
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('setValue');
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($engine);
$config->setMapped(false);
$form = $this->getForm($config);
$form = new SubmittedForm($config);
$this->mapper->mapFormsToData([$form], $car);
$this->assertSame($initialEngine, $car->engine);
}
public function testMapFormsToDataIgnoresUnsubmittedForms()
{
$initialEngine = new \stdClass();
$car = new \stdClass();
$car->engine = $initialEngine;
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('setValue');
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($engine);
$form = $this->getForm($config, true, false);
$form = new Form($config);
$this->mapper->mapFormsToData([$form], $car);
$this->assertSame($initialEngine, $car->engine);
}
public function testMapFormsToDataIgnoresEmptyData()
{
$initialEngine = new \stdClass();
$car = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('setValue');
$car->engine = $initialEngine;
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData(null);
$form = $this->getForm($config);
$form = new Form($config);
$this->mapper->mapFormsToData([$form], $car);
$this->assertSame($initialEngine, $car->engine);
}
public function testMapFormsToDataIgnoresUnsynchronized()
{
$initialEngine = new \stdClass();
$car = new \stdClass();
$car->engine = $initialEngine;
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('setValue');
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($engine);
$form = $this->getForm($config, false);
$form = new NotSynchronizedForm($config);
$this->mapper->mapFormsToData([$form], $car);
$this->assertSame($initialEngine, $car->engine);
}
public function testMapFormsToDataIgnoresDisabled()
{
$initialEngine = new \stdClass();
$car = new \stdClass();
$car->engine = $initialEngine;
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('setValue');
$propertyPath = new PropertyPath('engine');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($engine);
$config->setDisabled(true);
$form = $this->getForm($config);
$form = new Form($config);
$this->mapper->mapFormsToData([$form], $car);
$this->assertSame($initialEngine, $car->engine);
}
/**
@ -361,24 +307,19 @@ class PropertyPathMapperTest extends TestCase
{
$article = [];
$publishedAt = $date;
$article['publishedAt'] = clone $publishedAt;
$propertyPath = $this->getPropertyPath('[publishedAt]');
$this->propertyAccessor->expects($this->once())
->method('getValue')
->willReturn($article['publishedAt'])
;
$this->propertyAccessor->expects($this->never())
->method('setValue')
;
$publishedAtValue = clone $publishedAt;
$article['publishedAt'] = $publishedAtValue;
$propertyPath = new PropertyPath('[publishedAt]');
$config = new FormConfigBuilder('publishedAt', \get_class($publishedAt), $this->dispatcher);
$config->setByReference(false);
$config->setPropertyPath($propertyPath);
$config->setData($publishedAt);
$form = $this->getForm($config);
$form = new SubmittedForm($config);
$this->mapper->mapFormsToData([$form], $article);
$this->assertSame($publishedAtValue, $article['publishedAt']);
}
public function provideDate()
@ -389,3 +330,19 @@ class PropertyPathMapperTest extends TestCase
];
}
}
class SubmittedForm extends Form
{
public function isSubmitted()
{
return true;
}
}
class NotSynchronizedForm extends Form
{
public function isSynchronized()
{
return false;
}
}

View File

@ -12,9 +12,10 @@
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigInterface;
use Symfony\Component\Form\FormConfigBuilder;
use Symfony\Component\Form\FormEvent;
class FixUrlProtocolListenerTest extends TestCase
@ -22,7 +23,7 @@ class FixUrlProtocolListenerTest extends TestCase
public function testFixHttpUrl()
{
$data = 'www.symfony.com';
$form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock());
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
$event = new FormEvent($form, $data);
$filter = new FixUrlProtocolListener('http');
@ -34,7 +35,7 @@ class FixUrlProtocolListenerTest extends TestCase
public function testSkipKnownUrl()
{
$data = 'http://www.symfony.com';
$form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock());
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
$event = new FormEvent($form, $data);
$filter = new FixUrlProtocolListener('http');
@ -59,7 +60,7 @@ class FixUrlProtocolListenerTest extends TestCase
*/
public function testSkipOtherProtocol($url)
{
$form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock());
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
$event = new FormEvent($form, $url);
$filter = new FixUrlProtocolListener('http');

View File

@ -11,7 +11,9 @@
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormFactoryBuilder;
class MergeCollectionListenerArrayObjectTest extends MergeCollectionListenerTest
{
@ -22,6 +24,6 @@ class MergeCollectionListenerArrayObjectTest extends MergeCollectionListenerTest
protected function getBuilder($name = 'name')
{
return new FormBuilder($name, '\ArrayObject', $this->dispatcher, $this->factory);
return new FormBuilder($name, '\ArrayObject', new EventDispatcher(), (new FormFactoryBuilder())->getFormFactory());
}
}

View File

@ -11,7 +11,9 @@
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormFactoryBuilder;
class MergeCollectionListenerArrayTest extends MergeCollectionListenerTest
{
@ -22,6 +24,6 @@ class MergeCollectionListenerArrayTest extends MergeCollectionListenerTest
protected function getBuilder($name = 'name')
{
return new FormBuilder($name, null, $this->dispatcher, $this->factory);
return new FormBuilder($name, null, new EventDispatcher(), (new FormFactoryBuilder())->getFormFactory());
}
}

View File

@ -11,7 +11,9 @@
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormFactoryBuilder;
use Symfony\Component\Form\Tests\Fixtures\CustomArrayObject;
class MergeCollectionListenerCustomArrayObjectTest extends MergeCollectionListenerTest
@ -23,6 +25,6 @@ class MergeCollectionListenerCustomArrayObjectTest extends MergeCollectionListen
protected function getBuilder($name = 'name')
{
return new FormBuilder($name, 'Symfony\Component\Form\Tests\Fixtures\CustomArrayObject', $this->dispatcher, $this->factory);
return new FormBuilder($name, 'Symfony\Component\Form\Tests\Fixtures\CustomArrayObject', new EventDispatcher(), (new FormFactoryBuilder())->getFormFactory());
}
}

View File

@ -17,21 +17,15 @@ use Symfony\Component\Form\FormEvent;
abstract class MergeCollectionListenerTest extends TestCase
{
protected $dispatcher;
protected $factory;
protected $form;
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
$this->form = $this->getForm('axes');
}
protected function tearDown()
{
$this->dispatcher = null;
$this->factory = null;
$this->form = null;
}

View File

@ -13,36 +13,37 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
use Doctrine\Common\Collections\ArrayCollection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryBuilder;
class ResizeFormListenerTest extends TestCase
{
private $dispatcher;
private $factory;
private $form;
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
$this->factory = (new FormFactoryBuilder())->getFormFactory();
$this->form = $this->getBuilder()
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
}
protected function tearDown()
{
$this->dispatcher = null;
$this->factory = null;
$this->form = null;
}
protected function getBuilder($name = 'name')
{
return new FormBuilder($name, null, $this->dispatcher, $this->factory);
return new FormBuilder($name, null, new EventDispatcher(), $this->factory);
}
protected function getForm($name = 'name')
@ -50,31 +51,14 @@ class ResizeFormListenerTest extends TestCase
return $this->getBuilder($name)->getForm();
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
private function getDataMapper()
{
return $this->getMockBuilder('Symfony\Component\Form\DataMapperInterface')->getMock();
}
public function testPreSetDataResizesForm()
{
$this->form->add($this->getForm('0'));
$this->form->add($this->getForm('1'));
$this->factory->expects($this->at(0))
->method('createNamed')
->with(1, 'text', null, ['property_path' => '[1]', 'attr' => ['maxlength' => 10], 'auto_initialize' => false])
->will($this->returnValue($this->getForm('1')));
$this->factory->expects($this->at(1))
->method('createNamed')
->with(2, 'text', null, ['property_path' => '[2]', 'attr' => ['maxlength' => 10], 'auto_initialize' => false])
->will($this->returnValue($this->getForm('2')));
$data = [1 => 'string', 2 => 'string'];
$event = new FormEvent($this->form, $data);
$listener = new ResizeFormListener('text', ['attr' => ['maxlength' => 10]], false, false);
$listener = new ResizeFormListener(TextType::class, ['attr' => ['maxlength' => 10]], false, false);
$listener->preSetData($event);
$this->assertFalse($this->form->has('0'));
@ -95,26 +79,21 @@ class ResizeFormListenerTest extends TestCase
public function testPreSetDataDealsWithNullData()
{
$this->factory->expects($this->never())->method('createNamed');
$data = null;
$event = new FormEvent($this->form, $data);
$listener = new ResizeFormListener('text', [], false, false);
$listener = new ResizeFormListener(TextType::class, [], false, false);
$listener->preSetData($event);
$this->assertSame(0, $this->form->count());
}
public function testPreSubmitResizesUpIfAllowAdd()
{
$this->form->add($this->getForm('0'));
$this->factory->expects($this->once())
->method('createNamed')
->with(1, 'text', null, ['property_path' => '[1]', 'attr' => ['maxlength' => 10], 'auto_initialize' => false])
->will($this->returnValue($this->getForm('1')));
$data = [0 => 'string', 1 => 'string'];
$event = new FormEvent($this->form, $data);
$listener = new ResizeFormListener('text', ['attr' => ['maxlength' => 10]], true, false);
$listener = new ResizeFormListener(TextType::class, ['attr' => ['maxlength' => 10]], true, false);
$listener->preSubmit($event);
$this->assertTrue($this->form->has('0'));
@ -293,12 +272,12 @@ class ResizeFormListenerTest extends TestCase
$this->form->setData(['0' => ['name' => 'John'], '1' => ['name' => 'Jane']]);
$form1 = $this->getBuilder('0')
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$form1->add($this->getForm('name'));
$form2 = $this->getBuilder('1')
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$form2->add($this->getForm('name'));
$this->form->add($form1);

View File

@ -12,9 +12,10 @@
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Form\Extension\Core\EventListener\TrimListener;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigInterface;
use Symfony\Component\Form\FormConfigBuilder;
use Symfony\Component\Form\FormEvent;
class TrimListenerTest extends TestCase
@ -22,7 +23,7 @@ class TrimListenerTest extends TestCase
public function testTrim()
{
$data = ' Foo! ';
$form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock());
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
$event = new FormEvent($form, $data);
$filter = new TrimListener();
@ -34,7 +35,7 @@ class TrimListenerTest extends TestCase
public function testTrimSkipNonStrings()
{
$data = 1234;
$form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock());
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
$event = new FormEvent($form, $data);
$filter = new TrimListener();

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type;
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler;
use Symfony\Component\Form\NativeRequestHandler;
use Symfony\Component\Form\RequestHandlerInterface;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileTypeTest extends BaseTypeTest
@ -24,9 +25,7 @@ class FileTypeTest extends BaseTypeTest
public function testSetData()
{
$form = $this->factory->createBuilder(static::TESTED_TYPE)->getForm();
$data = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
->setConstructorArgs([__DIR__.'/../../../Fixtures/foo', 'foo'])
->getMock();
$data = new File(__DIR__.'/../../../Fixtures/foo', false);
$form->setData($data);
@ -40,7 +39,7 @@ class FileTypeTest extends BaseTypeTest
public function testSubmit(RequestHandlerInterface $requestHandler)
{
$form = $this->factory->createBuilder(static::TESTED_TYPE)->setRequestHandler($requestHandler)->getForm();
$data = $this->createUploadedFileMock($requestHandler, __DIR__.'/../../../Fixtures/foo', 'foo.jpg');
$data = $this->createUploadedFile($requestHandler, __DIR__.'/../../../Fixtures/foo', 'foo.jpg');
$form->submit($data);
@ -57,8 +56,8 @@ class FileTypeTest extends BaseTypeTest
])->setRequestHandler($requestHandler)->getForm();
$data = [
$this->createUploadedFileMock($requestHandler, __DIR__.'/../../../Fixtures/foo', 'foo.jpg'),
$this->createUploadedFileMock($requestHandler, __DIR__.'/../../../Fixtures/foo2', 'foo2.jpg'),
$this->createUploadedFile($requestHandler, __DIR__.'/../../../Fixtures/foo', 'foo.jpg'),
$this->createUploadedFile($requestHandler, __DIR__.'/../../../Fixtures/foo2', 'foo2.jpg'),
];
$form->setData($data);
@ -75,8 +74,8 @@ class FileTypeTest extends BaseTypeTest
])->setRequestHandler($requestHandler)->getForm();
$data = [
$this->createUploadedFileMock($requestHandler, __DIR__.'/../../../Fixtures/foo', 'foo.jpg'),
$this->createUploadedFileMock($requestHandler, __DIR__.'/../../../Fixtures/foo2', 'foo2.jpg'),
$this->createUploadedFile($requestHandler, __DIR__.'/../../../Fixtures/foo', 'foo.jpg'),
$this->createUploadedFile($requestHandler, __DIR__.'/../../../Fixtures/foo2', 'foo2.jpg'),
];
$form->submit($data);
@ -94,7 +93,7 @@ class FileTypeTest extends BaseTypeTest
{
$form = $this->factory->createBuilder(static::TESTED_TYPE)->setRequestHandler($requestHandler)->getForm();
$form->submit([
'file' => $this->createUploadedFileMock($requestHandler, __DIR__.'/../../../Fixtures/foo', 'foo.jpg'),
'file' => $this->createUploadedFile($requestHandler, __DIR__.'/../../../Fixtures/foo', 'foo.jpg'),
]);
$this->assertEquals('', $form->createView()->vars['value']);
@ -152,8 +151,8 @@ class FileTypeTest extends BaseTypeTest
->getForm();
$form->submit([
'file:///etc/passwd',
$this->createUploadedFileMock(new HttpFoundationRequestHandler(), __DIR__.'/../../../Fixtures/foo', 'foo.jpg'),
$this->createUploadedFileMock(new NativeRequestHandler(), __DIR__.'/../../../Fixtures/foo2', 'foo2.jpg'),
$this->createUploadedFile(new HttpFoundationRequestHandler(), __DIR__.'/../../../Fixtures/foo', 'foo.jpg'),
$this->createUploadedFile(new NativeRequestHandler(), __DIR__.'/../../../Fixtures/foo2', 'foo2.jpg'),
]);
$this->assertCount(1, $form->getData());
@ -185,7 +184,7 @@ class FileTypeTest extends BaseTypeTest
];
}
private function createUploadedFileMock(RequestHandlerInterface $requestHandler, $path, $originalName)
private function createUploadedFile(RequestHandlerInterface $requestHandler, $path, $originalName)
{
if ($requestHandler instanceof HttpFoundationRequestHandler) {
return new UploadedFile($path, $originalName, null, null, true);

View File

@ -50,4 +50,45 @@ class IntegerTypeTest extends BaseTypeTest
$this->assertSame($expectedData, $form->getNormData());
$this->assertSame($expectedData, $form->getData());
}
public function testSubmittedLargeIntegersAreNotCastToFloat()
{
if (4 === \PHP_INT_SIZE) {
$this->markTestSkipped('This test requires a 64bit PHP.');
}
$form = $this->factory->create(static::TESTED_TYPE);
$form->submit('201803221011791');
$this->assertSame(201803221011791, $form->getData());
$this->assertSame('201803221011791', $form->getViewData());
}
public function testTooSmallIntegersAreNotValid()
{
if (4 === \PHP_INT_SIZE) {
$min = '-2147483649';
} else {
$min = '-9223372036854775808';
}
$form = $this->factory->create(static::TESTED_TYPE);
$form->submit($min);
$this->assertFalse($form->isSynchronized());
}
public function testTooGreatIntegersAreNotValid()
{
if (4 === \PHP_INT_SIZE) {
$max = '2147483648';
} else {
$max = '9223372036854775808';
}
$form = $this->factory->create(static::TESTED_TYPE);
$form->submit($max);
$this->assertFalse($form->isSynchronized());
}
}

View File

@ -12,9 +12,13 @@
namespace Symfony\Component\Form\Tests\Extension\Csrf\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryBuilder;
use Symfony\Component\Security\Csrf\CsrfTokenManager;
class CsrfValidationListenerTest extends TestCase
{
@ -25,11 +29,11 @@ class CsrfValidationListenerTest extends TestCase
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
$this->tokenManager = $this->getMockBuilder('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface')->getMock();
$this->dispatcher = new EventDispatcher();
$this->factory = (new FormFactoryBuilder())->getFormFactory();
$this->tokenManager = new CsrfTokenManager();
$this->form = $this->getBuilder()
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
}
@ -46,11 +50,6 @@ class CsrfValidationListenerTest extends TestCase
return new FormBuilder('post', null, $this->dispatcher, $this->factory, ['compound' => true]);
}
protected function getDataMapper()
{
return $this->getMockBuilder('Symfony\Component\Form\DataMapperInterface')->getMock();
}
// https://github.com/symfony/symfony/pull/5838
public function testStringFormData()
{

View File

@ -47,7 +47,7 @@ class HttpFoundationRequestHandlerTest extends AbstractRequestHandlerTest
return new HttpFoundationRequestHandler($this->serverParams);
}
protected function getMockFile($suffix = '')
protected function getUploadedFile($suffix = '')
{
return new UploadedFile(__DIR__.'/../../Fixtures/foo'.$suffix, 'foo'.$suffix);
}

View File

@ -11,12 +11,16 @@
namespace Symfony\Component\Form\Tests\Extension\Validator\Constraints;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormFactoryBuilder;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\SubmitButtonBuilder;
use Symfony\Component\Translation\IdentityTranslator;
@ -34,39 +38,28 @@ use Symfony\Component\Validator\Validation;
class FormValidatorTest extends ConstraintValidatorTestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var EventDispatcherInterface
*/
private $dispatcher;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var FormFactoryInterface
*/
private $factory;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $serverParams;
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
$this->serverParams = $this->getMockBuilder('Symfony\Component\Form\Extension\Validator\Util\ServerParams')->setMethods(['getNormalizedIniPostMaxSize', 'getContentLength'])->getMock();
$this->dispatcher = new EventDispatcher();
$this->factory = (new FormFactoryBuilder())->getFormFactory();
parent::setUp();
$this->constraint = new Form();
}
protected function createValidator()
{
return new FormValidator($this->serverParams);
}
public function testValidate()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$options = ['validation_groups' => ['group1', 'group2']];
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
@ -81,7 +74,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testValidateConstraints()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$constraint1 = new NotNull(['groups' => ['group1', 'group2']]);
$constraint2 = new NotBlank(['groups' => 'group2']);
@ -107,11 +100,11 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testValidateChildIfValidConstraint()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$parent = $this->getBuilder('parent')
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$options = [
'validation_groups' => ['group1', 'group2'],
@ -131,11 +124,11 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testDontValidateIfParentWithoutValidConstraint()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$parent = $this->getBuilder('parent', null)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$options = ['validation_groups' => ['group1', 'group2']];
$form = $this->getBuilder('name', '\stdClass', $options)->getForm();
@ -165,13 +158,13 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testValidateConstraintsOptionEvenIfNoValidConstraint()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$constraint1 = new NotNull(['groups' => ['group1', 'group2']]);
$constraint2 = new NotBlank(['groups' => 'group2']);
$parent = $this->getBuilder('parent', null)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$options = [
'validation_groups' => ['group1', 'group2'],
@ -192,7 +185,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testDontValidateIfNoValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$form = $this->getBuilder('name', '\stdClass', [
'validation_groups' => [],
@ -211,13 +204,11 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testDontValidateConstraintsIfNoValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$constraint1 = $this->getMockBuilder('Symfony\Component\Validator\Constraint')->getMock();
$constraint2 = $this->getMockBuilder('Symfony\Component\Validator\Constraint')->getMock();
$object = new \stdClass();
$options = [
'validation_groups' => [],
'constraints' => [$constraint1, $constraint2],
'constraints' => [new NotBlank(), new NotNull()],
];
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
@ -235,7 +226,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testDontValidateIfNotSynchronized()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$form = $this->getBuilder('name', '\stdClass', [
'invalid_message' => 'invalid_message_key',
@ -269,7 +260,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testAddInvalidErrorEvenIfNoValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$form = $this->getBuilder('name', '\stdClass', [
'invalid_message' => 'invalid_message_key',
@ -304,14 +295,12 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testDontValidateConstraintsIfNotSynchronized()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$constraint1 = $this->getMockBuilder('Symfony\Component\Validator\Constraint')->getMock();
$constraint2 = $this->getMockBuilder('Symfony\Component\Validator\Constraint')->getMock();
$object = new \stdClass();
$options = [
'invalid_message' => 'invalid_message_key',
'validation_groups' => ['group1', 'group2'],
'constraints' => [$constraint1, $constraint2],
'constraints' => [new NotBlank(), new NotBlank()],
];
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
@ -339,7 +328,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase
// https://github.com/symfony/symfony/issues/4359
public function testDontMarkInvalidIfAnyChildIsNotSynchronized()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$object->child = 'bar';
$failingTransformer = new CallbackTransformer(
function ($data) { return $data; },
@ -350,7 +340,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
->setData($object)
->addViewTransformer($failingTransformer)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->add(
$this->getBuilder('child')
->addViewTransformer($failingTransformer)
@ -369,7 +359,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testHandleGroupSequenceValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$options = ['validation_groups' => new GroupSequence(['group1', 'group2'])];
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
@ -385,7 +375,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testHandleCallbackValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$options = ['validation_groups' => [$this, 'getValidationGroups']];
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
@ -400,7 +390,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testDontExecuteFunctionNames()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$options = ['validation_groups' => 'header'];
$form = $this->getBuilder('name', '\stdClass', $options)
->setData($object)
@ -415,7 +405,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testHandleClosureValidationGroups()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$options = ['validation_groups' => function (FormInterface $form) {
return ['group1', 'group2'];
}];
@ -432,11 +422,11 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testUseValidationGroupOfClickedButton()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$parent = $this->getBuilder('parent')
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$form = $this->getForm('name', '\stdClass', [
'validation_groups' => 'form_group',
@ -459,11 +449,11 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testDontUseValidationGroupOfUnclickedButton()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$parent = $this->getBuilder('parent')
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$form = $this->getForm('name', '\stdClass', [
'validation_groups' => 'form_group',
@ -486,12 +476,12 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testUseInheritedValidationGroup()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$parentOptions = ['validation_groups' => 'group'];
$parent = $this->getBuilder('parent', null, $parentOptions)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$formOptions = ['constraints' => [new Valid()]];
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
@ -508,12 +498,12 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testUseInheritedCallbackValidationGroup()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$parentOptions = ['validation_groups' => [$this, 'getValidationGroups']];
$parent = $this->getBuilder('parent', null, $parentOptions)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$formOptions = ['constraints' => [new Valid()]];
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
@ -530,7 +520,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testUseInheritedClosureValidationGroup()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$parentOptions = [
'validation_groups' => function (FormInterface $form) {
@ -539,7 +529,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
];
$parent = $this->getBuilder('parent', null, $parentOptions)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->getForm();
$formOptions = ['constraints' => [new Valid()]];
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
@ -556,7 +546,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testAppendPropertyPath()
{
$object = $this->getMockBuilder('\stdClass')->getMock();
$object = new \stdClass();
$form = $this->getBuilder('name', '\stdClass')
->setData($object)
->getForm();
@ -585,7 +575,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
{
$form = $this->getBuilder('parent', null, ['extra_fields_message' => 'Extra!'])
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->add($this->getBuilder('child'))
->getForm();
@ -606,7 +596,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
{
$form = $this->getBuilder('parent', null, ['extra_fields_message' => 'Extra!'])
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->add($this->getBuilder('child'))
->getForm();
@ -625,22 +615,21 @@ class FormValidatorTest extends ConstraintValidatorTestCase
public function testNoViolationIfAllowExtraData()
{
$context = $this->getMockExecutionContext();
$form = $this
->getBuilder('parent', null, ['allow_extra_fields' => true])
->setCompound(true)
->setDataMapper($this->getDataMapper())
->setDataMapper(new PropertyPathMapper())
->add($this->getBuilder('child'))
->getForm();
$form->submit(['foo' => 'bar']);
$context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator());
$context->expects($this->never())
->method('addViolation');
$form->submit(['foo' => 'bar']);
$this->validator->initialize($context);
$this->validator->validate($form, new Form());
$this->assertCount(0, $context->getViolations());
}
/**
@ -674,22 +663,9 @@ class FormValidatorTest extends ConstraintValidatorTestCase
$this->assertSame($constraint, $context->getViolations()->get(0)->getConstraint());
}
private function getMockExecutionContext()
protected function createValidator()
{
$context = $this->getMockBuilder('Symfony\Component\Validator\Context\ExecutionContextInterface')->getMock();
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$contextualValidator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ContextualValidatorInterface')->getMock();
$validator->expects($this->any())
->method('inContext')
->with($context)
->will($this->returnValue($contextualValidator));
$context->expects($this->any())
->method('getValidator')
->will($this->returnValue($validator));
return $context;
return new FormValidator();
}
private function getBuilder(string $name = 'name', string $dataClass = null, array $options = []): FormBuilder
@ -713,12 +689,4 @@ class FormValidatorTest extends ConstraintValidatorTestCase
return $builder->getForm();
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
private function getDataMapper()
{
return $this->getMockBuilder('Symfony\Component\Form\DataMapperInterface')->getMock();
}
}

View File

@ -12,40 +12,41 @@
namespace Symfony\Component\Form\Tests\Extension\Validator\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Extension\Validator\Constraints\Form as FormConstraint;
use Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener;
use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormConfigBuilder;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryBuilder;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class ValidationListenerTest extends TestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var EventDispatcherInterface
*/
private $dispatcher;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var FormFactoryInterface
*/
private $factory;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var ValidatorInterface
*/
private $validator;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $violationMapper;
/**
* @var ValidationListener
*/
@ -59,40 +60,18 @@ class ValidationListenerTest extends TestCase
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
$this->validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$this->violationMapper = $this->getMockBuilder('Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapperInterface')->getMock();
$this->listener = new ValidationListener($this->validator, $this->violationMapper);
$this->dispatcher = new EventDispatcher();
$this->factory = (new FormFactoryBuilder())->getFormFactory();
$this->validator = Validation::createValidator();
$this->listener = new ValidationListener($this->validator, new ViolationMapper());
$this->message = 'Message';
$this->messageTemplate = 'Message template';
$this->params = ['foo' => 'bar'];
}
private function getConstraintViolation($code = null)
{
return new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, 'prop.path', null, null, $code, new FormConstraint());
}
private function getBuilder($name = 'name', $propertyPath = null, $dataClass = null)
{
$builder = new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory);
$builder->setPropertyPath(new PropertyPath($propertyPath ?: $name));
$builder->setAttribute('error_mapping', []);
$builder->setErrorBubbling(false);
$builder->setMapped(true);
return $builder;
}
private function getForm($name = 'name', $propertyPath = null, $dataClass = null)
{
return $this->getBuilder($name, $propertyPath, $dataClass)->getForm();
}
private function createForm($name = '', $compound = false)
{
$config = new FormBuilder($name, null, $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), $this->getMockBuilder(FormFactoryInterface::class)->getMock());
$config = new FormBuilder($name, null, new EventDispatcher(), (new FormFactoryBuilder())->getFormFactory());
$config->setCompound($compound);
if ($compound) {
@ -105,35 +84,29 @@ class ValidationListenerTest extends TestCase
// More specific mapping tests can be found in ViolationMapperTest
public function testMapViolation()
{
$violation = $this->getConstraintViolation();
$form = $this->getForm('street');
$violation = new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, 'data', null, null, null, new FormConstraint());
$form = new Form(new FormConfigBuilder('street', null, new EventDispatcher()));
$form->submit(null);
$this->validator->expects($this->once())
->method('validate')
->will($this->returnValue([$violation]));
$validator = new DummyValidator($violation);
$listener = new ValidationListener($validator, new ViolationMapper());
$listener->validateForm(new FormEvent($form, null));
$this->violationMapper->expects($this->once())
->method('mapViolation')
->with($violation, $form, false);
$this->listener->validateForm(new FormEvent($form, null));
$this->assertCount(1, $form->getErrors());
$this->assertSame($violation, $form->getErrors()[0]->getCause());
}
public function testMapViolationAllowsNonSyncIfInvalid()
{
$violation = $this->getConstraintViolation(FormConstraint::NOT_SYNCHRONIZED_ERROR);
$form = $this->getForm('street');
$violation = new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, 'data', null, null, FormConstraint::NOT_SYNCHRONIZED_ERROR, new FormConstraint());
$form = new SubmittedNotSynchronizedForm(new FormConfigBuilder('street', null, new EventDispatcher()));
$this->validator->expects($this->once())
->method('validate')
->will($this->returnValue([$violation]));
$validator = new DummyValidator($violation);
$listener = new ValidationListener($validator, new ViolationMapper());
$listener->validateForm(new FormEvent($form, null));
$this->violationMapper->expects($this->once())
->method('mapViolation')
// pass true now
->with($violation, $form, true);
$this->listener->validateForm(new FormEvent($form, null));
$this->assertCount(1, $form->getErrors());
$this->assertSame($violation, $form->getErrors()[0]->getCause());
}
public function testValidateIgnoresNonRoot()
@ -143,36 +116,72 @@ class ValidationListenerTest extends TestCase
$form = $this->createForm('', true);
$form->add($childForm);
$this->validator->expects($this->never())
->method('validate');
$this->violationMapper->expects($this->never())
->method('mapViolation');
$form->submit(['child' => null]);
$this->listener->validateForm(new FormEvent($childForm, null));
$this->assertTrue($childForm->isValid());
}
public function testValidateWithEmptyViolationList()
{
$form = $this->createForm();
$this->validator
->expects($this->once())
->method('validate')
->will($this->returnValue(new ConstraintViolationList()));
$this->violationMapper
->expects($this->never())
->method('mapViolation');
$form->submit(null);
$this->listener->validateForm(new FormEvent($form, null));
}
public function testValidatorInterface()
{
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$listener = new ValidationListener($validator, $this->violationMapper);
$this->assertAttributeSame($validator, 'validator', $listener);
$this->assertTrue($form->isValid());
}
}
class SubmittedNotSynchronizedForm extends Form
{
public function isSubmitted()
{
return true;
}
public function isSynchronized()
{
return false;
}
}
class DummyValidator implements ValidatorInterface
{
private $violation;
public function __construct(ConstraintViolationInterface $violation)
{
$this->violation = $violation;
}
public function getMetadataFor($value)
{
}
public function hasMetadataFor($value)
{
}
public function validate($value, $constraints = null, $groups = null)
{
return [$this->violation];
}
public function validateProperty($object, $propertyName, $groups = null)
{
}
public function validatePropertyValue($objectOrClass, $propertyName, $value, $groups = null)
{
}
public function startContext()
{
}
public function inContext(ExecutionContextInterface $context)
{
}
}

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Form\Tests\Extension\Validator\Type;
use Symfony\Component\Form\Extension\Validator\Type\FormTypeValidatorExtension;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
use Symfony\Component\Form\Forms;
use Symfony\Component\Form\Test\Traits\ValidatorExtensionTrait;
@ -56,14 +55,6 @@ class FormTypeValidatorExtensionTest extends BaseValidatorExtensionTest
$this->assertSame([$valid], $form->getConfig()->getOption('constraints'));
}
public function testValidatorInterface()
{
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
$formTypeValidatorExtension = new FormTypeValidatorExtension($validator);
$this->assertAttributeSame($validator, 'validator', $formTypeValidatorExtension);
}
public function testGroupSequenceWithConstraintsOption()
{
$form = Forms::createFormFactoryBuilder()

View File

@ -21,18 +21,11 @@ class UploadValidatorExtensionTest extends TypeTestCase
{
public function testPostMaxSizeTranslation()
{
$translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();
$translator->expects($this->any())
->method('trans')
->with($this->equalTo('old max {{ max }}!'))
->willReturn('translated max {{ max }}!');
$extension = new UploadValidatorExtension($translator);
$extension = new UploadValidatorExtension(new DummyTranslator());
$resolver = new OptionsResolver();
$resolver->setDefault('post_max_size_message', 'old max {{ max }}!');
$resolver->setDefault('upload_max_size_message', function (Options $options, $message) {
$resolver->setDefault('upload_max_size_message', function (Options $options) {
return function () use ($options) {
return $options['post_max_size_message'];
};
@ -44,3 +37,25 @@ class UploadValidatorExtensionTest extends TypeTestCase
$this->assertEquals('translated max {{ max }}!', $options['upload_max_size_message']());
}
}
class DummyTranslator implements TranslatorInterface
{
public function trans($id, array $parameters = [], $domain = null, $locale = null)
{
return 'translated max {{ max }}!';
}
public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null)
{
return 'translated max {{ max }}!';
}
public function setLocale($locale)
{
}
public function getLocale()
{
return 'en';
}
}

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\Util;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
class ServerParamsTest extends TestCase
{
@ -32,8 +33,8 @@ class ServerParamsTest extends TestCase
public function testGetContentLengthFromRequest()
{
$request = Request::create('http://foo', 'GET', [], [], [], ['CONTENT_LENGTH' => 1024]);
$requestStack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->setMethods(['getCurrentRequest'])->getMock();
$requestStack->expects($this->once())->method('getCurrentRequest')->will($this->returnValue($request));
$requestStack = new RequestStack();
$requestStack->push($request);
$serverParams = new ServerParams($requestStack);
$this->assertEquals(1024, $serverParams->getContentLength());
@ -42,11 +43,7 @@ class ServerParamsTest extends TestCase
/** @dataProvider getGetPostMaxSizeTestData */
public function testGetPostMaxSize($size, $bytes)
{
$serverParams = $this->getMockBuilder('Symfony\Component\Form\Extension\Validator\Util\ServerParams')->setMethods(['getNormalizedIniPostMaxSize'])->getMock();
$serverParams
->expects($this->any())
->method('getNormalizedIniPostMaxSize')
->will($this->returnValue(strtoupper($size)));
$serverParams = new DummyServerParams($size);
$this->assertEquals($bytes, $serverParams->getPostMaxSize());
}
@ -70,3 +67,20 @@ class ServerParamsTest extends TestCase
];
}
}
class DummyServerParams extends ServerParams
{
private $size;
public function __construct($size)
{
parent::__construct();
$this->size = $size;
}
public function getNormalizedIniPostMaxSize()
{
return $this->size;
}
}

View File

@ -12,37 +12,37 @@
namespace Symfony\Component\Form\Tests\Extension\Validator;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Validator\Constraints\Form as FormConstraint;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser;
use Symfony\Component\Form\Form;
use Symfony\Component\Validator\Mapping\CascadingStrategy;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Mapping\TraversalStrategy;
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
use Symfony\Component\Validator\Validation;
class ValidatorExtensionTest extends TestCase
{
public function test2Dot5ValidationApi()
{
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\RecursiveValidator')
->disableOriginalConstructor()
->getMock();
$metadata = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')
->setMethods(['addConstraint', 'addPropertyConstraint'])
->disableOriginalConstructor()
->getMock();
$metadata = new ClassMetadata(Form::class);
$validator->expects($this->once())
->method('getMetadataFor')
->with($this->identicalTo('Symfony\Component\Form\Form'))
->will($this->returnValue($metadata));
$metadataFactory = new FakeMetadataFactory();
$metadataFactory->addMetadata($metadata);
// Verify that the constraints are added
$metadata->expects($this->once())
->method('addConstraint')
->with($this->isInstanceOf('Symfony\Component\Form\Extension\Validator\Constraints\Form'));
$metadata->expects($this->once())
->method('addPropertyConstraint')
->with('children', $this->isInstanceOf('Symfony\Component\Validator\Constraints\Valid'));
$validator = Validation::createValidatorBuilder()
->setMetadataFactory($metadataFactory)
->getValidator();
$extension = new ValidatorExtension($validator);
$guesser = $extension->loadTypeGuesser();
$this->assertInstanceOf('Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser', $guesser);
$this->assertInstanceOf(ValidatorTypeGuesser::class, $extension->loadTypeGuesser());
$this->assertCount(1, $metadata->getConstraints());
$this->assertInstanceOf(FormConstraint::class, $metadata->getConstraints()[0]);
$this->assertSame(CascadingStrategy::CASCADE, $metadata->getPropertyMetadata('children')[0]->cascadingStrategy);
$this->assertSame(TraversalStrategy::IMPLICIT, $metadata->getPropertyMetadata('children')[0]->traversalStrategy);
}
}

View File

@ -23,6 +23,8 @@ use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\Range;
use Symfony\Component\Validator\Constraints\Type;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
/**
* @author franek <franek@chicour.net>
@ -45,18 +47,15 @@ class ValidatorTypeGuesserTest extends TestCase
private $metadata;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MetadataFactoryInterface
*/
private $metadataFactory;
protected function setUp()
{
$this->metadata = new ClassMetadata(self::TEST_CLASS);
$this->metadataFactory = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface')->getMock();
$this->metadataFactory->expects($this->any())
->method('getMetadataFor')
->with(self::TEST_CLASS)
->will($this->returnValue($this->metadata));
$this->metadataFactory = new FakeMetadataFactory();
$this->metadataFactory->addMetadata($this->metadata);
$this->guesser = new ValidatorTypeGuesser($this->metadataFactory);
}

View File

@ -12,8 +12,11 @@
namespace Symfony\Component\Form\Tests\Extension\Validator\ViolationMapper;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigBuilder;
@ -34,7 +37,7 @@ class ViolationMapperTest extends TestCase
const LEVEL_2 = 3;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var EventDispatcherInterface
*/
private $dispatcher;
@ -60,7 +63,7 @@ class ViolationMapperTest extends TestCase
protected function setUp()
{
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->dispatcher = new EventDispatcher();
$this->mapper = new ViolationMapper();
$this->message = 'Message';
$this->messageTemplate = 'Message template';
@ -76,7 +79,7 @@ class ViolationMapperTest extends TestCase
$config->setInheritData($inheritData);
$config->setPropertyPath($propertyPath);
$config->setCompound(true);
$config->setDataMapper($this->getDataMapper());
$config->setDataMapper(new PropertyPathMapper());
if (!$synchronized) {
$config->addViewTransformer(new CallbackTransformer(
@ -88,14 +91,6 @@ class ViolationMapperTest extends TestCase
return new Form($config);
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
private function getDataMapper()
{
return $this->getMockBuilder('Symfony\Component\Form\DataMapperInterface')->getMock();
}
/**
* @param $propertyPath
*

View File

@ -179,6 +179,59 @@ class NativeRequestHandlerTest extends AbstractRequestHandlerTest
$this->assertFalse($form->isSubmitted());
}
public function testFormIgnoresMethodFieldIfRequestMethodIsMatched()
{
$form = $this->createForm('foo', 'PUT', true);
$form->add($this->createForm('bar'));
$this->setRequestData('PUT', [
'foo' => [
'_method' => 'PUT',
'bar' => 'baz',
],
]);
$this->requestHandler->handleRequest($form, $this->request);
$this->assertSame([], $form->getExtraData());
}
public function testFormDoesNotIgnoreMethodFieldIfRequestMethodIsNotMatched()
{
$form = $this->createForm('foo', 'PUT', true);
$form->add($this->createForm('bar'));
$this->setRequestData('PUT', [
'foo' => [
'_method' => 'DELETE',
'bar' => 'baz',
],
]);
$this->requestHandler->handleRequest($form, $this->request);
$this->assertSame(['_method' => 'DELETE'], $form->getExtraData());
}
public function testMethodSubFormIsSubmitted()
{
$form = $this->createForm('foo', 'PUT', true);
$form->add($this->createForm('_method'));
$form->add($this->createForm('bar'));
$this->setRequestData('PUT', [
'foo' => [
'_method' => 'PUT',
'bar' => 'baz',
],
]);
$this->requestHandler->handleRequest($form, $this->request);
$this->assertTrue($form->get('_method')->isSubmitted());
$this->assertSame('PUT', $form->get('_method')->getData());
}
protected function setRequestData($method, $data, $files = [])
{
if ('GET' === $method) {
@ -201,7 +254,7 @@ class NativeRequestHandlerTest extends AbstractRequestHandlerTest
return new NativeRequestHandler($this->serverParams);
}
protected function getMockFile($suffix = '')
protected function getUploadedFile($suffix = '')
{
return [
'name' => 'upload'.$suffix.'.txt',

View File

@ -34,9 +34,6 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable
*/
private $cloner;
/**
* @internal
*/
public function serialize()
{
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
@ -45,9 +42,6 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable
return $isCalledFromOverridingMethod ? $this->data : serialize($this->data);
}
/**
* @internal
*/
public function unserialize($data)
{
$this->data = \is_array($data) ? $data : unserialize($data);

View File

@ -136,9 +136,6 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
$this->clonesIndex = 0;
}
/**
* @internal
*/
public function serialize()
{
if ($this->clonesCount !== $this->clonesIndex) {
@ -155,9 +152,6 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
return $ser;
}
/**
* @internal
*/
public function unserialize($data)
{
$this->data = unserialize($data);

View File

@ -204,9 +204,9 @@ class GraphvizDumper implements DumperInterface
/**
* @internal
*/
protected function escape(string $string): string
protected function escape($value): string
{
return addslashes($string);
return \is_bool($value) ? ($value ? '1' : '0') : \addslashes($value);
}
private function addAttributes(array $attributes): string