From 1976d29e014635921b61397a8e974dbe5a56ec6b Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sat, 5 Jan 2019 10:56:34 -0500 Subject: [PATCH 01/11] Always pass $key to NullAdapter->createCacheItem Previously, if this were called, it would throw an ArgumentCountError. I'm assuming existing code always checks hasItem, so this bug hasn't impacted many people. This was noticed via static analysis. The get() method was added to NullAdapter in symfony 4.2 --- src/Symfony/Component/Cache/Adapter/NullAdapter.php | 2 +- .../Cache/Tests/Adapter/NullAdapterTest.php | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/Adapter/NullAdapter.php b/src/Symfony/Component/Cache/Adapter/NullAdapter.php index 3c88a6902a9e..cd6a937b6c40 100644 --- a/src/Symfony/Component/Cache/Adapter/NullAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/NullAdapter.php @@ -42,7 +42,7 @@ function ($key) { */ public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { - return $callback(($this->createCacheItem)()); + return $callback(($this->createCacheItem)($key)); } /** diff --git a/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php index 73e5cad5529a..7dd08ad865fa 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php @@ -34,6 +34,19 @@ public function testGetItem() $this->assertNull($item->get(), "Item's value must be null when isHit is false."); } + public function testGet() + { + $adapter = $this->createCachePool(); + + $fetched = []; + $item = $adapter->get('myKey', function ($item) use (&$fetched) { $fetched[] = $item; }); + $this->assertCount(1, $fetched); + $item = $fetched[0]; + $this->assertFalse($item->isHit()); + $this->assertNull($item->get(), "Item's value must be null when isHit is false."); + $this->assertSame('myKey', $item->getKey()); + } + public function testHasItem() { $this->assertFalse($this->createCachePool()->hasItem('key')); From 38a9d8b6a3d4abdcb560052889eb4d7c41743c14 Mon Sep 17 00:00:00 2001 From: Konstantin Grachev Date: Sat, 5 Jan 2019 00:04:29 +0300 Subject: [PATCH 02/11] [Bugfix] MemcachedSessionHandler::close() must close connection --- .../Session/Storage/Handler/MemcachedSessionHandler.php | 2 +- .../Session/Storage/Handler/MemcachedSessionHandlerTest.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php index 61a7afd90400..8bcd75cc6e68 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php @@ -62,7 +62,7 @@ public function __construct(\Memcached $memcached, array $options = array()) */ public function close() { - return true; + return $this->memcached->quit(); } /** diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php index 2a114801056c..422293084380 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php @@ -63,6 +63,12 @@ public function testOpenSession() public function testCloseSession() { + $this->memcached + ->expects($this->once()) + ->method('quit') + ->will($this->returnValue(true)) + ; + $this->assertTrue($this->storage->close()); } From 2791edf1fb8fcdcc6546a7d32b59a20815b0a928 Mon Sep 17 00:00:00 2001 From: Mathieu Lechat Date: Wed, 26 Dec 2018 17:27:02 +0100 Subject: [PATCH 03/11] [Form] Changed UrlType input type to text when default_protocol is not null --- .../AbstractBootstrap3LayoutTest.php | 20 +++++++++++++++++-- src/Symfony/Bridge/Twig/composer.json | 2 +- .../Bundle/FrameworkBundle/composer.json | 2 +- .../Form/Extension/Core/Type/UrlType.php | 13 ++++++++++++ .../Form/Tests/AbstractLayoutTest.php | 19 ++++++++++++++++-- 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php index ae62a40f604f..ebfb105826b3 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php @@ -2385,13 +2385,29 @@ public function testTimezoneWithPlaceholder() ); } - public function testUrl() + public function testUrlWithDefaultProtocol() { $url = 'http://www.google.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']); $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']], '/input + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@value="http://www.google.com?foo1=bar1&foo2=bar2"] + [@inputmode="url"] +' + ); + } + + public function testUrlWithoutDefaultProtocol() + { + $url = 'http://www.google.com?foo1=bar1&foo2=bar2'; + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]); + + $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']], + '/input [@type="url"] [@name="name"] [@class="my&class form-control"] diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 7d646c001043..58e90971bec1 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -23,7 +23,7 @@ "symfony/asset": "~2.8|~3.0|~4.0", "symfony/dependency-injection": "~2.8|~3.0|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", - "symfony/form": "^3.4.16|^4.1.5", + "symfony/form": "^3.4.22|~4.1.11|^4.2.3", "symfony/http-foundation": "^3.3.11|~4.0", "symfony/http-kernel": "~3.2|~4.0", "symfony/polyfill-intl-icu": "~1.0", diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index c1aad683ad69..c8ed98787e15 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -39,7 +39,7 @@ "symfony/css-selector": "~2.8|~3.0|~4.0", "symfony/dom-crawler": "~2.8|~3.0|~4.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/form": "~3.4|~4.0", + "symfony/form": "^3.4.22|~4.1.11|^4.2.3", "symfony/expression-language": "~2.8|~3.0|~4.0", "symfony/process": "~2.8|~3.0|~4.0", "symfony/security-core": "~3.2|~4.0", diff --git a/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php b/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php index 17460688b7fd..39b9d2d20828 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php @@ -14,6 +14,8 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; class UrlType extends AbstractType @@ -28,6 +30,17 @@ public function buildForm(FormBuilderInterface $builder, array $options) } } + /** + * {@inheritdoc} + */ + public function buildView(FormView $view, FormInterface $form, array $options) + { + if ($options['default_protocol']) { + $view->vars['attr']['inputmode'] = 'url'; + $view->vars['type'] = 'text'; + } + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index bb7fc197abfc..0e749b780c78 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -2170,10 +2170,25 @@ public function testTimezoneWithPlaceholder() ); } - public function testUrl() + public function testUrlWithDefaultProtocol() { $url = 'http://www.google.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']); + + $this->assertWidgetMatchesXpath($form->createView(), [], +'/input + [@type="text"] + [@name="name"] + [@value="http://www.google.com?foo1=bar1&foo2=bar2"] + [@inputmode="url"] +' + ); + } + + public function testUrlWithoutDefaultProtocol() + { + $url = 'http://www.google.com?foo1=bar1&foo2=bar2'; + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]); $this->assertWidgetMatchesXpath($form->createView(), [], '/input From b979fff6b8c3f2bff4faa46798e1c1dd5270b229 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Sun, 13 Jan 2019 13:45:12 +0100 Subject: [PATCH 04/11] [Debug][ErrorHandler] Preserve our error handler when a logger set another one --- src/Symfony/Component/Debug/ErrorHandler.php | 4 ++ .../Debug/Tests/ErrorHandlerTest.php | 44 +++++++++++++++++++ .../Fixtures/LoggerThatSetAnErrorHandler.php | 14 ++++++ 3 files changed, 62 insertions(+) create mode 100644 src/Symfony/Component/Debug/Tests/Fixtures/LoggerThatSetAnErrorHandler.php diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 64857ed44722..22a6426dab7e 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -523,6 +523,10 @@ public function handleError($type, $message, $file, $line) $this->loggers[$type][0]->log($level, $logMessage, $errorAsException ? ['exception' => $errorAsException] : []); } finally { $this->isRecursive = false; + + if (!\defined('HHVM_VERSION')) { + set_error_handler([$this, __FUNCTION__]); + } } } diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 98d9f6143da0..6e0afd55cacf 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -12,10 +12,13 @@ namespace Symfony\Component\Debug\Tests; use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; +use Psr\Log\NullLogger; use Symfony\Component\Debug\BufferingLogger; use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\Debug\Exception\SilencedErrorContext; +use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler; /** * ErrorHandlerTest. @@ -321,6 +324,8 @@ public function testHandleDeprecation() $handler = new ErrorHandler(); $handler->setDefaultLogger($logger); @$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []); + + restore_error_handler(); } /** @@ -583,4 +588,43 @@ public function testCustomExceptionHandler() $handler->handleException(new \Exception()); } + + /** + * @dataProvider errorHandlerIsNotLostWhenLoggingProvider + */ + public function testErrorHandlerIsNotLostWhenLogging($customErrorHandlerHasBeenPreviouslyDefined, LoggerInterface $logger) + { + try { + if ($customErrorHandlerHasBeenPreviouslyDefined) { + set_error_handler('count'); + } + + $handler = ErrorHandler::register(); + $handler->setDefaultLogger($logger); + + @trigger_error('foo', E_USER_DEPRECATED); + @trigger_error('bar', E_USER_DEPRECATED); + + $this->assertSame([$handler, 'handleError'], set_error_handler('var_dump')); + + restore_error_handler(); + + if ($customErrorHandlerHasBeenPreviouslyDefined) { + restore_error_handler(); + } + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + public function errorHandlerIsNotLostWhenLoggingProvider() + { + return [ + [false, new NullLogger()], + [true, new NullLogger()], + [false, new LoggerThatSetAnErrorHandler()], + [true, new LoggerThatSetAnErrorHandler()], + ]; + } } diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/LoggerThatSetAnErrorHandler.php b/src/Symfony/Component/Debug/Tests/Fixtures/LoggerThatSetAnErrorHandler.php new file mode 100644 index 000000000000..7545039cf85a --- /dev/null +++ b/src/Symfony/Component/Debug/Tests/Fixtures/LoggerThatSetAnErrorHandler.php @@ -0,0 +1,14 @@ + Date: Fri, 11 Jan 2019 11:31:44 +0100 Subject: [PATCH 05/11] [Cache] fix used variable name --- .../Component/Cache/Simple/Psr6Cache.php | 2 +- .../Cache/Tests/Fixtures/ExternalAdapter.php | 4 +-- .../Cache/Tests/Simple/Psr6CacheTest.php | 10 +++----- .../Tests/Simple/Psr6CacheWithAdapterTest.php | 25 +++++++++++++++++++ .../Simple/Psr6CacheWithoutAdapterTest.php | 25 +++++++++++++++++++ 5 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithAdapterTest.php create mode 100644 src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php diff --git a/src/Symfony/Component/Cache/Simple/Psr6Cache.php b/src/Symfony/Component/Cache/Simple/Psr6Cache.php index 29c039f2c169..fceb9ba70fd8 100644 --- a/src/Symfony/Component/Cache/Simple/Psr6Cache.php +++ b/src/Symfony/Component/Cache/Simple/Psr6Cache.php @@ -154,7 +154,7 @@ public function getMultiple($keys, $default = null) $values[$key] = $item->isHit() ? $item->get() : $default; } - return $value; + return $values; } foreach ($items as $key => $item) { diff --git a/src/Symfony/Component/Cache/Tests/Fixtures/ExternalAdapter.php b/src/Symfony/Component/Cache/Tests/Fixtures/ExternalAdapter.php index 779a374ec7ab..deb0b3bc3402 100644 --- a/src/Symfony/Component/Cache/Tests/Fixtures/ExternalAdapter.php +++ b/src/Symfony/Component/Cache/Tests/Fixtures/ExternalAdapter.php @@ -24,9 +24,9 @@ class ExternalAdapter implements CacheItemPoolInterface { private $cache; - public function __construct() + public function __construct(int $defaultLifetime = 0) { - $this->cache = new ArrayAdapter(); + $this->cache = new ArrayAdapter($defaultLifetime); } public function getItem($key) diff --git a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php index 1bc75c906035..65d48a978c50 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php @@ -11,13 +11,9 @@ namespace Symfony\Component\Cache\Tests\Simple; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\Simple\Psr6Cache; -/** - * @group time-sensitive - */ -class Psr6CacheTest extends CacheTestCase +abstract class Psr6CacheTest extends CacheTestCase { protected $skippedTests = [ 'testPrune' => 'Psr6Cache just proxies', @@ -25,6 +21,8 @@ class Psr6CacheTest extends CacheTestCase public function createSimpleCache($defaultLifetime = 0) { - return new Psr6Cache(new FilesystemAdapter('', $defaultLifetime)); + return new Psr6Cache($this->createCacheItemPool($defaultLifetime)); } + + abstract protected function createCacheItemPool($defaultLifetime = 0); } diff --git a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithAdapterTest.php b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithAdapterTest.php new file mode 100644 index 000000000000..46da9354d6db --- /dev/null +++ b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithAdapterTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Adapter\FilesystemAdapter; + +/** + * @group time-sensitive + */ +class Psr6CacheWithAdapterTest extends Psr6CacheTest +{ + protected function createCacheItemPool($defaultLifetime = 0) + { + return new FilesystemAdapter('', $defaultLifetime); + } +} diff --git a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php new file mode 100644 index 000000000000..a8c4164dcbb1 --- /dev/null +++ b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter; + +/** + * @group time-sensitive + */ +class Psr6CacheWithoutAdapterTest extends Psr6CacheTest +{ + protected function createCacheItemPool($defaultLifetime = 0) + { + return new ExternalAdapter($defaultLifetime); + } +} From 0b44ad79c66a7dc2c138ca46966a963c4a3ae710 Mon Sep 17 00:00:00 2001 From: George Mponos Date: Mon, 14 Jan 2019 23:07:15 +0200 Subject: [PATCH 06/11] [Serializer] Docblock about throwing exceptions on serializer --- .../Component/Serializer/Normalizer/DenormalizerInterface.php | 4 +++- .../Component/Serializer/Normalizer/NormalizerInterface.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php index c3a2bb535632..7a12d20f1132 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php +++ b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Serializer\Normalizer; use Symfony\Component\Serializer\Exception\BadMethodCallException; +use Symfony\Component\Serializer\Exception\ExceptionInterface; use Symfony\Component\Serializer\Exception\ExtraAttributesException; use Symfony\Component\Serializer\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Exception\LogicException; @@ -41,8 +42,9 @@ interface DenormalizerInterface * @throws ExtraAttributesException Occurs when the item doesn't have attribute to receive given data * @throws LogicException Occurs when the normalizer is not supposed to denormalize * @throws RuntimeException Occurs if the class cannot be instantiated + * @throws ExceptionInterface Occurs for all the other cases of errors */ - public function denormalize($data, $class, $format = null, array $context = array()); + public function denormalize($data, $class, $format = null, array $context = []); /** * Checks whether the given class is supported for denormalization by this normalizer. diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php index 5cccdb336009..02a211858492 100644 --- a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php +++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Serializer\Normalizer; use Symfony\Component\Serializer\Exception\CircularReferenceException; +use Symfony\Component\Serializer\Exception\ExceptionInterface; use Symfony\Component\Serializer\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Exception\LogicException; @@ -35,8 +36,9 @@ interface NormalizerInterface * @throws CircularReferenceException Occurs when the normalizer detects a circular reference when no circular * reference handler can fix it * @throws LogicException Occurs when the normalizer is not called in an expected context + * @throws ExceptionInterface Occurs for all the other cases of errors */ - public function normalize($object, $format = null, array $context = array()); + public function normalize($object, $format = null, array $context = []); /** * Checks whether the given class is supported for normalization by this normalizer. From 0d9de7e7e357323d920964c3c57ac86d92e573fa Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 18 Jan 2019 18:22:25 +0100 Subject: [PATCH 07/11] [Form] ensure compatibility with older PHPUnit mocks --- .../Tests/Controller/ControllerTraitTest.php | 4 +- .../Tests/Profiler/TemplateManagerTest.php | 37 ++-- src/Symfony/Component/Form/Form.php | 8 +- .../Component/Form/Tests/AbstractFormTest.php | 20 -- .../Form/Tests/AbstractRequestHandlerTest.php | 185 ++++++++---------- .../Component/Form/Tests/CompoundFormTest.php | 160 ++++++++------- .../FixUrlProtocolListenerTest.php | 8 +- .../MergeCollectionListenerTest.php | 5 - .../EventListener/ResizeFormListenerTest.php | 5 - .../Core/EventListener/TrimListenerTest.php | 6 +- .../CsrfValidationListenerTest.php | 5 - .../HttpFoundationRequestHandlerTest.php | 4 +- .../EventListener/ValidationListenerTest.php | 36 ++-- .../Form/Tests/NativeRequestHandlerTest.php | 81 ++++---- .../Form/Tests/ResolvedFormTypeTest.php | 10 +- .../Component/Form/Tests/SimpleFormTest.php | 15 +- .../Tests/Mapping/ClassMetadataTest.php | 33 ++-- .../Validator/TraceableValidatorTest.php | 7 +- 18 files changed, 291 insertions(+), 338 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php index 01e36d0b7158..e72c558b7edc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php @@ -15,6 +15,7 @@ use Symfony\Bundle\FrameworkBundle\Tests\TestCase; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormConfigInterface; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\HttpFoundation\JsonResponse; @@ -487,8 +488,7 @@ public function testCreateNotFoundException() public function testCreateForm() { - $config = $this->getMockBuilder('Symfony\Component\Form\FormConfigInterface')->getMock(); - $form = new Form($config); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $formFactory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock(); $formFactory->expects($this->once())->method('create')->willReturn($form); diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php index 7d797ec84f9d..18d4cc44b402 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php @@ -13,6 +13,7 @@ use Symfony\Bundle\WebProfilerBundle\Profiler\TemplateManager; use Symfony\Bundle\WebProfilerBundle\Tests\TestCase; +use Symfony\Component\HttpKernel\Profiler\Profile; use Twig\Environment; /** @@ -57,8 +58,7 @@ protected function setUp() */ public function testGetNameOfInvalidTemplate() { - $profile = $this->mockProfile(); - $this->templateManager->getName($profile, 'notexistingpanel'); + $this->templateManager->getName(new Profile('token'), 'notexistingpanel'); } /** @@ -71,12 +71,7 @@ public function testGetNameValidTemplate() ->withAnyParameters() ->will($this->returnCallback([$this, 'profilerHasCallback'])); - $profile = $this->mockProfile(); - $profile->expects($this->any()) - ->method('hasCollector') - ->will($this->returnCallback([$this, 'profileHasCollectorCallback'])); - - $this->assertEquals('FooBundle:Collector:foo.html.twig', $this->templateManager->getName($profile, 'foo')); + $this->assertEquals('FooBundle:Collector:foo.html.twig', $this->templateManager->getName(new ProfileDummy(), 'foo')); } /** @@ -85,17 +80,12 @@ public function testGetNameValidTemplate() */ public function testGetTemplates() { - $profile = $this->mockProfile(); - $profile->expects($this->any()) - ->method('hasCollector') - ->will($this->returnCallback([$this, 'profilerHasCallback'])); - $this->profiler->expects($this->any()) ->method('has') ->withAnyParameters() ->will($this->returnCallback([$this, 'profileHasCollectorCallback'])); - $result = $this->templateManager->getTemplates($profile); + $result = $this->templateManager->getTemplates(new ProfileDummy()); $this->assertArrayHasKey('foo', $result); $this->assertArrayNotHasKey('bar', $result); $this->assertArrayNotHasKey('baz', $result); @@ -155,3 +145,22 @@ protected function mockProfiler() return $this->profiler; } } + +class ProfileDummy extends Profile +{ + public function __construct() + { + parent::__construct('token'); + } + + public function hasCollector($name) + { + switch ($name) { + case 'foo': + case 'bar': + return true; + default: + return false; + } + } +} diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 1ab5d146efd6..1822cf6e18ac 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -532,9 +532,11 @@ public function submit($submittedData, $clearMissing = true) $submittedData = null; } elseif (is_scalar($submittedData)) { $submittedData = (string) $submittedData; - } elseif (!$this->config->getOption('allow_file_upload') && $this->config->getRequestHandler()->isFileUpload($submittedData)) { - $submittedData = null; - $this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, file upload given.'); + } elseif ($this->config->getRequestHandler()->isFileUpload($submittedData)) { + if (!$this->config->getOption('allow_file_upload')) { + $submittedData = null; + $this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, file upload given.'); + } } elseif (\is_array($submittedData) && !$this->config->getCompound() && !$this->config->hasOption('multiple')) { $submittedData = null; $this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, array given.'); diff --git a/src/Symfony/Component/Form/Tests/AbstractFormTest.php b/src/Symfony/Component/Form/Tests/AbstractFormTest.php index 235aa3fa98d0..00d9e0fbd485 100644 --- a/src/Symfony/Component/Form/Tests/AbstractFormTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractFormTest.php @@ -65,26 +65,6 @@ protected function getBuilder($name = 'name', EventDispatcherInterface $dispatch return new FormBuilder($name, $dataClass, $dispatcher ?: $this->dispatcher, $this->factory, $options); } - /** - * @param string $name - * - * @return \PHPUnit_Framework_MockObject_MockObject - */ - protected function getMockForm($name = 'name') - { - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); - $config = $this->getMockBuilder('Symfony\Component\Form\FormConfigInterface')->getMock(); - - $form->expects($this->any()) - ->method('getName') - ->will($this->returnValue($name)); - $form->expects($this->any()) - ->method('getConfig') - ->will($this->returnValue($config)); - - return $form; - } - /** * @return \PHPUnit_Framework_MockObject_MockObject */ diff --git a/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php b/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php index 2c3de1184b63..dd73dcde23e4 100644 --- a/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php @@ -12,6 +12,10 @@ namespace Symfony\Component\Form\Tests; use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormBuilder; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormFactory; use Symfony\Component\Form\Forms; @@ -66,17 +70,16 @@ public function methodProvider() */ public function testSubmitIfNameInRequest($method) { - $form = $this->getMockForm('param1', $method); + $form = $this->createForm('param1', $method); $this->setRequestData($method, [ 'param1' => 'DATA', ]); - $form->expects($this->once()) - ->method('submit') - ->with('DATA', 'PATCH' !== $method); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($form->isSubmitted()); + $this->assertSame('DATA', $form->getData()); } /** @@ -84,7 +87,7 @@ public function testSubmitIfNameInRequest($method) */ public function testDoNotSubmitIfWrongRequestMethod($method) { - $form = $this->getMockForm('param1', $method); + $form = $this->createForm('param1', $method); $otherMethod = 'POST' === $method ? 'PUT' : 'POST'; @@ -92,10 +95,9 @@ public function testDoNotSubmitIfWrongRequestMethod($method) 'param1' => 'DATA', ]); - $form->expects($this->never()) - ->method('submit'); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertFalse($form->isSubmitted()); } /** @@ -103,16 +105,15 @@ public function testDoNotSubmitIfWrongRequestMethod($method) */ public function testDoNoSubmitSimpleFormIfNameNotInRequestAndNotGetRequest($method) { - $form = $this->getMockForm('param1', $method, false); + $form = $this->createForm('param1', $method, false); $this->setRequestData($method, [ 'paramx' => [], ]); - $form->expects($this->never()) - ->method('submit'); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertFalse($form->isSubmitted()); } /** @@ -120,30 +121,28 @@ public function testDoNoSubmitSimpleFormIfNameNotInRequestAndNotGetRequest($meth */ public function testDoNotSubmitCompoundFormIfNameNotInRequestAndNotGetRequest($method) { - $form = $this->getMockForm('param1', $method, true); + $form = $this->createForm('param1', $method, true); $this->setRequestData($method, [ 'paramx' => [], ]); - $form->expects($this->never()) - ->method('submit'); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertFalse($form->isSubmitted()); } public function testDoNotSubmitIfNameNotInRequestAndGetRequest() { - $form = $this->getMockForm('param1', 'GET'); + $form = $this->createForm('param1', 'GET'); $this->setRequestData('GET', [ 'paramx' => [], ]); - $form->expects($this->never()) - ->method('submit'); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertFalse($form->isSubmitted()); } /** @@ -151,24 +150,28 @@ public function testDoNotSubmitIfNameNotInRequestAndGetRequest() */ public function testSubmitFormWithEmptyNameIfAtLeastOneFieldInRequest($method) { - $form = $this->getMockForm('', $method); - $form->expects($this->any()) - ->method('all') - ->will($this->returnValue([ - 'param1' => $this->getMockForm('param1'), - 'param2' => $this->getMockForm('param2'), - ])); + $form = $this->createForm('', $method, true); + $form->add($this->createForm('param1')); + $form->add($this->createForm('param2')); $this->setRequestData($method, $requestData = [ 'param1' => 'submitted value', 'paramx' => 'submitted value', ]); - $form->expects($this->once()) - ->method('submit') - ->with($requestData, 'PATCH' !== $method); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($form->isSubmitted()); + $this->assertTrue($form->get('param1')->isSubmitted()); + $this->assertSame('submitted value', $form->get('param1')->getData()); + + if ('PATCH' === $method) { + $this->assertFalse($form->get('param2')->isSubmitted()); + } else { + $this->assertTrue($form->get('param2')->isSubmitted()); + } + + $this->assertNull($form->get('param2')->getData()); } /** @@ -176,22 +179,17 @@ public function testSubmitFormWithEmptyNameIfAtLeastOneFieldInRequest($method) */ public function testDoNotSubmitFormWithEmptyNameIfNoFieldInRequest($method) { - $form = $this->getMockForm('', $method); - $form->expects($this->any()) - ->method('all') - ->will($this->returnValue([ - 'param1' => $this->getMockForm('param1'), - 'param2' => $this->getMockForm('param2'), - ])); + $form = $this->createForm('', $method, true); + $form->add($this->createForm('param1')); + $form->add($this->createForm('param2')); $this->setRequestData($method, [ 'paramx' => 'submitted value', ]); - $form->expects($this->never()) - ->method('submit'); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertFalse($form->isSubmitted()); } /** @@ -199,7 +197,9 @@ public function testDoNotSubmitFormWithEmptyNameIfNoFieldInRequest($method) */ public function testMergeParamsAndFiles($method) { - $form = $this->getMockForm('param1', $method); + $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(); $this->setRequestData($method, [ @@ -212,14 +212,11 @@ public function testMergeParamsAndFiles($method) ], ]); - $form->expects($this->once()) - ->method('submit') - ->with([ - 'field1' => 'DATA', - 'field2' => $file, - ], 'PATCH' !== $method); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($form->isSubmitted()); + $this->assertSame('DATA', $form->get('field1')->getData()); + $this->assertSame($file, $form->get('field2')->getData()); } /** @@ -227,7 +224,7 @@ public function testMergeParamsAndFiles($method) */ public function testParamTakesPrecedenceOverFile($method) { - $form = $this->getMockForm('param1', $method); + $form = $this->createForm('param1', $method); $file = $this->getMockFile(); $this->setRequestData($method, [ @@ -236,11 +233,10 @@ public function testParamTakesPrecedenceOverFile($method) 'param1' => $file, ]); - $form->expects($this->once()) - ->method('submit') - ->with('DATA', 'PATCH' !== $method); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($form->isSubmitted()); + $this->assertSame('DATA', $form->getData()); } /** @@ -248,7 +244,9 @@ public function testParamTakesPrecedenceOverFile($method) */ public function testSubmitFileIfNoParam($method) { - $form = $this->getMockForm('param1', $method); + $form = $this->createBuilder('param1', false, ['allow_file_upload' => true]) + ->setMethod($method) + ->getForm(); $file = $this->getMockFile(); $this->setRequestData($method, [ @@ -257,11 +255,10 @@ public function testSubmitFileIfNoParam($method) 'param1' => $file, ]); - $form->expects($this->once()) - ->method('submit') - ->with($file, 'PATCH' !== $method); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($form->isSubmitted()); + $this->assertSame($file, $form->getData()); } /** @@ -269,7 +266,9 @@ public function testSubmitFileIfNoParam($method) */ public function testSubmitMultipleFiles($method) { - $form = $this->getMockForm('param1', $method); + $form = $this->createBuilder('param1', false, ['allow_file_upload' => true]) + ->setMethod($method) + ->getForm(); $file = $this->getMockFile(); $this->setRequestData($method, [ @@ -280,32 +279,10 @@ public function testSubmitMultipleFiles($method) 'param3' => $this->getMockFile('3'), ]); - $form->expects($this->once()) - ->method('submit') - ->with($file, 'PATCH' !== $method); - $this->requestHandler->handleRequest($form, $this->request); - } - - /** - * @dataProvider methodExceptGetProvider - */ - public function testSubmitFileWithNamelessForm($method) - { - $form = $this->getMockForm(null, $method); - $file = $this->getMockFile(); - - $this->setRequestData($method, [ - '' => null, - ], [ - '' => $file, - ]); - - $form->expects($this->once()) - ->method('submit') - ->with($file, 'PATCH' !== $method); - $this->requestHandler->handleRequest($form, $this->request); + $this->assertTrue($form->isSubmitted()); + $this->assertSame($file, $form->getData()); } /** @@ -371,24 +348,26 @@ abstract protected function getMockFile($suffix = ''); abstract protected function getInvalidFile(); - protected function getMockForm($name, $method = null, $compound = true) + protected function createForm($name, $method = null, $compound = false) + { + $config = $this->createBuilder($name, $compound); + + if (null !== $method) { + $config->setMethod($method); + } + + return new Form($config); + } + + protected function createBuilder($name, $compound = false, array $options = []) { - $config = $this->getMockBuilder('Symfony\Component\Form\FormConfigInterface')->getMock(); - $config->expects($this->any()) - ->method('getMethod') - ->will($this->returnValue($method)); - $config->expects($this->any()) - ->method('getCompound') - ->will($this->returnValue($compound)); - - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); - $form->expects($this->any()) - ->method('getName') - ->will($this->returnValue($name)); - $form->expects($this->any()) - ->method('getConfig') - ->will($this->returnValue($config)); - - return $form; + $builder = new FormBuilder($name, null, new EventDispatcher(), $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock(), $options); + $builder->setCompound($compound); + + if ($compound) { + $builder->setDataMapper(new PropertyPathMapper()); + } + + return $builder; } } diff --git a/src/Symfony/Component/Form/Tests/CompoundFormTest.php b/src/Symfony/Component/Form/Tests/CompoundFormTest.php index 85c7431bcf70..ba4f26ecc9d8 100644 --- a/src/Symfony/Component/Form/Tests/CompoundFormTest.php +++ b/src/Symfony/Component/Form/Tests/CompoundFormTest.php @@ -11,9 +11,12 @@ namespace Symfony\Component\Form\Tests; +use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler; use Symfony\Component\Form\FormError; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\Forms; use Symfony\Component\Form\FormView; use Symfony\Component\Form\SubmitButtonBuilder; @@ -69,40 +72,35 @@ public function testDisabledFormsValidEvenIfChildrenInvalid() public function testSubmitForwardsNullIfNotClearMissingButValueIsExplicitlyNull() { - $child = $this->getMockForm('firstName'); + $child = $this->createForm('firstName', false); $this->form->add($child); - $child->expects($this->once()) - ->method('submit') - ->with($this->equalTo(null)); - $this->form->submit(['firstName' => null], false); + + $this->assertNull($this->form->get('firstName')->getData()); } public function testSubmitForwardsNullIfValueIsMissing() { - $child = $this->getMockForm('firstName'); + $child = $this->createForm('firstName', false); $this->form->add($child); - $child->expects($this->once()) - ->method('submit') - ->with($this->equalTo(null)); - $this->form->submit([]); + + $this->assertNull($this->form->get('firstName')->getData()); } public function testSubmitDoesNotForwardNullIfNotClearMissing() { - $child = $this->getMockForm('firstName'); + $child = $this->createForm('firstName', false); $this->form->add($child); - $child->expects($this->never()) - ->method('submit'); - $this->form->submit([], false); + + $this->assertFalse($child->isSubmitted()); } public function testSubmitDoesNotAddExtraFieldForNullValues() @@ -120,15 +118,22 @@ public function testSubmitDoesNotAddExtraFieldForNullValues() public function testClearMissingFlagIsForwarded() { - $child = $this->getMockForm('firstName'); + $personForm = $this->createForm('person'); - $this->form->add($child); + $firstNameForm = $this->createForm('firstName', false); + $personForm->add($firstNameForm); - $child->expects($this->once()) - ->method('submit') - ->with($this->equalTo('foo'), false); + $lastNameForm = $this->createForm('lastName', false); + $lastNameForm->setData('last name'); + $personForm->add($lastNameForm); - $this->form->submit(['firstName' => 'foo'], false); + $this->form->add($personForm); + $this->form->submit(['person' => ['firstName' => 'foo']], false); + + $this->assertTrue($firstNameForm->isSubmitted()); + $this->assertSame('foo', $firstNameForm->getData()); + $this->assertFalse($lastNameForm->isSubmitted()); + $this->assertSame('last name', $lastNameForm->getData()); } public function testCloneChildren() @@ -145,10 +150,8 @@ public function testCloneChildren() public function testNotEmptyIfChildNotEmpty() { - $child = $this->getMockForm(); - $child->expects($this->once()) - ->method('isEmpty') - ->will($this->returnValue(false)); + $child = $this->createForm('name', false); + $child->setData('foo'); $this->form->setData(null); $this->form->add($child); @@ -400,29 +403,25 @@ public function testSetDataSupportsDynamicAdditionAndRemovalOfChildren() ->setDataMapper(new PropertyPathMapper()) ->getForm(); - $child = $this->getMockForm('child'); - $childToBeRemoved = $this->getMockForm('removed'); - $childToBeAdded = $this->getMockForm('added'); - - $form->add($child); - $form->add($childToBeRemoved); - - $child->expects($this->once()) - ->method('setData') - ->will($this->returnCallback(function () use ($form, $childToBeAdded) { + $childToBeRemoved = $this->createForm('removed', false); + $childToBeAdded = $this->createForm('added', false); + $child = $this->getBuilder('child', new EventDispatcher()) + ->setCompound(true) + ->setDataMapper(new PropertyPathMapper()) + ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($form, $childToBeAdded) { $form->remove('removed'); $form->add($childToBeAdded); - })); - - $childToBeRemoved->expects($this->never()) - ->method('setData'); + }) + ->getForm(); - // once when it it is created, once when it is added - $childToBeAdded->expects($this->exactly(2)) - ->method('setData'); + $form->add($child); + $form->add($childToBeRemoved); // pass NULL to all children $form->setData([]); + + $this->assertFalse($form->has('removed')); + $this->assertTrue($form->has('added')); } public function testSetDataMapsViewDataToChildren() @@ -453,30 +452,25 @@ public function testSetDataMapsViewDataToChildren() public function testSubmitSupportsDynamicAdditionAndRemovalOfChildren() { - $child = $this->getMockForm('child'); - $childToBeRemoved = $this->getMockForm('removed'); - $childToBeAdded = $this->getMockForm('added'); - - $this->form->add($child); - $this->form->add($childToBeRemoved); - $form = $this->form; - $child->expects($this->once()) - ->method('submit') - ->will($this->returnCallback(function () use ($form, $childToBeAdded) { + $childToBeRemoved = $this->createForm('removed'); + $childToBeAdded = $this->createForm('added'); + $child = $this->getBuilder('child') + ->addEventListener(FormEvents::PRE_SUBMIT, function () use ($form, $childToBeAdded) { $form->remove('removed'); $form->add($childToBeAdded); - })); - - $childToBeRemoved->expects($this->never()) - ->method('submit'); + }) + ->getForm(); - $childToBeAdded->expects($this->once()) - ->method('submit'); + $this->form->add($child); + $this->form->add($childToBeRemoved); // pass NULL to all children $this->form->submit([]); + + $this->assertFalse($childToBeRemoved->isSubmitted()); + $this->assertTrue($childToBeAdded->isSubmitted()); } public function testSubmitMapsSubmittedChildrenOntoExistingViewData() @@ -880,12 +874,24 @@ public function testGetErrorsDeepRecursive() public function testCreateViewWithChildren() { $type = $this->getMockBuilder('Symfony\Component\Form\ResolvedFormTypeInterface')->getMock(); + $type1 = $this->getMockBuilder('Symfony\Component\Form\ResolvedFormTypeInterface')->getMock(); + $type2 = $this->getMockBuilder('Symfony\Component\Form\ResolvedFormTypeInterface')->getMock(); $options = ['a' => 'Foo', 'b' => 'Bar']; - $field1 = $this->getMockForm('foo'); - $field2 = $this->getMockForm('bar'); + $field1 = $this->getBuilder('foo') + ->setType($type1) + ->getForm(); + $field2 = $this->getBuilder('bar') + ->setType($type2) + ->getForm(); $view = new FormView(); $field1View = new FormView(); + $type1 + ->method('createView') + ->will($this->returnValue($field1View)); $field2View = new FormView(); + $type2 + ->method('createView') + ->will($this->returnValue($field2View)); $this->form = $this->getBuilder('form', null, null, $options) ->setCompound(true) @@ -912,24 +918,8 @@ public function testCreateViewWithChildren() ->with($view, $this->form, $options) ->will($this->returnCallback($assertChildViewsEqual([]))); - // Then add the first child form - $field1->expects($this->once()) - ->method('createView') - ->will($this->returnValue($field1View)); - - // Then the second child form - $field2->expects($this->once()) - ->method('createView') - ->will($this->returnValue($field2View)); - - // Again build the view for the form itself. This time the child views - // exist. - $type->expects($this->once()) - ->method('finishView') - ->with($view, $this->form, $options) - ->will($this->returnCallback($assertChildViewsEqual(['foo' => $field1View, 'bar' => $field2View]))); - $this->assertSame($view, $this->form->createView()); + $this->assertSame(['foo' => $field1View, 'bar' => $field2View], $view->children); } public function testNoClickedButtonBeforeSubmission() @@ -1022,7 +1012,7 @@ public function testDisabledButtonIsNotSubmitted() ->getForm(); $form = $this->createForm() - ->add($this->getBuilder('text')->getForm()) + ->add($this->createForm('text', false)) ->add($submit) ; @@ -1067,11 +1057,17 @@ public function testFileUpload() $this->assertNull($this->form->get('bar')->getData()); } - protected function createForm() + protected function createForm($name = 'name', $compound = true) { - return $this->getBuilder() - ->setCompound(true) - ->setDataMapper($this->getDataMapper()) - ->getForm(); + $builder = $this->getBuilder($name); + + if ($compound) { + $builder + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ; + } + + return $builder->getForm(); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php index 7861e12197e4..0182aa23d301 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php @@ -13,6 +13,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormConfigInterface; use Symfony\Component\Form\FormEvent; class FixUrlProtocolListenerTest extends TestCase @@ -20,7 +22,7 @@ class FixUrlProtocolListenerTest extends TestCase public function testFixHttpUrl() { $data = 'www.symfony.com'; - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $event = new FormEvent($form, $data); $filter = new FixUrlProtocolListener('http'); @@ -32,7 +34,7 @@ public function testFixHttpUrl() public function testSkipKnownUrl() { $data = 'http://www.symfony.com'; - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $event = new FormEvent($form, $data); $filter = new FixUrlProtocolListener('http'); @@ -57,7 +59,7 @@ public function provideUrlsWithSupportedProtocols() */ public function testSkipOtherProtocol($url) { - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $event = new FormEvent($form, $url); $filter = new FixUrlProtocolListener('http'); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php index 41b7d18bd5be..98cd78385a80 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php @@ -44,11 +44,6 @@ protected function getForm($name = 'name', $propertyPath = null) return $this->getBuilder($name)->setAttribute('property_path', $propertyPath)->getForm(); } - protected function getMockForm() - { - return $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); - } - public function getBooleanMatrix1() { return [ diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php index daa3a8de0948..84a8c1db8884 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php @@ -58,11 +58,6 @@ private function getDataMapper() return $this->getMockBuilder('Symfony\Component\Form\DataMapperInterface')->getMock(); } - protected function getMockForm() - { - return $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); - } - public function testPreSetDataResizesForm() { $this->form->add($this->getForm('0')); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php index 1ecd3ad705cf..78dae1bd8223 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php @@ -13,6 +13,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Extension\Core\EventListener\TrimListener; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormConfigInterface; use Symfony\Component\Form\FormEvent; class TrimListenerTest extends TestCase @@ -20,7 +22,7 @@ class TrimListenerTest extends TestCase public function testTrim() { $data = ' Foo! '; - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $event = new FormEvent($form, $data); $filter = new TrimListener(); @@ -32,7 +34,7 @@ public function testTrim() public function testTrimSkipNonStrings() { $data = 1234; - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $event = new FormEvent($form, $data); $filter = new TrimListener(); diff --git a/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php index 5bad58888406..43e9acad057c 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php @@ -51,11 +51,6 @@ protected function getDataMapper() return $this->getMockBuilder('Symfony\Component\Form\DataMapperInterface')->getMock(); } - protected function getMockForm() - { - return $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); - } - // https://github.com/symfony/symfony/pull/5838 public function testStringFormData() { diff --git a/src/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php b/src/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php index f414a511b04c..5597e835542d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php @@ -26,7 +26,7 @@ class HttpFoundationRequestHandlerTest extends AbstractRequestHandlerTest */ public function testRequestShouldNotBeNull() { - $this->requestHandler->handleRequest($this->getMockForm('name', 'GET')); + $this->requestHandler->handleRequest($this->createForm('name', 'GET')); } /** @@ -34,7 +34,7 @@ public function testRequestShouldNotBeNull() */ public function testRequestShouldBeInstanceOfRequest() { - $this->requestHandler->handleRequest($this->getMockForm('name', 'GET'), new \stdClass()); + $this->requestHandler->handleRequest($this->createForm('name', 'GET'), new \stdClass()); } protected function setRequestData($method, $data, $files = []) diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php index 5cda7eeaf733..855a90d2e347 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php @@ -12,10 +12,14 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\EventListener; use PHPUnit\Framework\TestCase; -use Symfony\Component\Form\Extension\Validator\Constraints\Form; +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\Form; use Symfony\Component\Form\FormBuilder; use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\PropertyAccess\PropertyPath; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; @@ -67,7 +71,7 @@ protected function setUp() private function getConstraintViolation($code = null) { - return new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, 'prop.path', null, null, $code, new Form()); + 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) @@ -86,9 +90,16 @@ private function getForm($name = 'name', $propertyPath = null, $dataClass = null return $this->getBuilder($name, $propertyPath, $dataClass)->getForm(); } - private function getMockForm() + private function createForm($name = '', $compound = false) { - return $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $config = new FormBuilder($name, null, $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), $this->getMockBuilder(FormFactoryInterface::class)->getMock()); + $config->setCompound($compound); + + if ($compound) { + $config->setDataMapper(new PropertyPathMapper()); + } + + return new Form($config); } // More specific mapping tests can be found in ViolationMapperTest @@ -110,7 +121,7 @@ public function testMapViolation() public function testMapViolationAllowsNonSyncIfInvalid() { - $violation = $this->getConstraintViolation(Form::NOT_SYNCHRONIZED_ERROR); + $violation = $this->getConstraintViolation(FormConstraint::NOT_SYNCHRONIZED_ERROR); $form = $this->getForm('street'); $this->validator->expects($this->once()) @@ -127,10 +138,10 @@ public function testMapViolationAllowsNonSyncIfInvalid() public function testValidateIgnoresNonRoot() { - $form = $this->getMockForm(); - $form->expects($this->once()) - ->method('isRoot') - ->will($this->returnValue(false)); + $childForm = $this->createForm('child'); + + $form = $this->createForm('', true); + $form->add($childForm); $this->validator->expects($this->never()) ->method('validate'); @@ -138,15 +149,12 @@ public function testValidateIgnoresNonRoot() $this->violationMapper->expects($this->never()) ->method('mapViolation'); - $this->listener->validateForm(new FormEvent($form, null)); + $this->listener->validateForm(new FormEvent($childForm, null)); } public function testValidateWithEmptyViolationList() { - $form = $this->getMockForm(); - $form->expects($this->once()) - ->method('isRoot') - ->will($this->returnValue(true)); + $form = $this->createForm(); $this->validator ->expects($this->once()) diff --git a/src/Symfony/Component/Form/Tests/NativeRequestHandlerTest.php b/src/Symfony/Component/Form/Tests/NativeRequestHandlerTest.php index db4902e34b9d..077f477d4a23 100644 --- a/src/Symfony/Component/Form/Tests/NativeRequestHandlerTest.php +++ b/src/Symfony/Component/Form/Tests/NativeRequestHandlerTest.php @@ -53,12 +53,12 @@ protected function tearDown() */ public function testRequestShouldBeNull() { - $this->requestHandler->handleRequest($this->getMockForm('name', 'GET'), 'request'); + $this->requestHandler->handleRequest($this->createForm('name', 'GET'), 'request'); } public function testMethodOverrideHeaderTakesPrecedenceIfPost() { - $form = $this->getMockForm('param1', 'PUT'); + $form = $this->createForm('param1', 'PUT'); $this->setRequestData('POST', [ 'param1' => 'DATA', @@ -66,16 +66,15 @@ public function testMethodOverrideHeaderTakesPrecedenceIfPost() $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT'; - $form->expects($this->once()) - ->method('submit') - ->with('DATA'); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($form->isSubmitted()); + $this->assertSame('DATA', $form->getData()); } public function testConvertEmptyUploadedFilesToNull() { - $form = $this->getMockForm('param1', 'POST', false); + $form = $this->createForm('param1', 'POST', false); $this->setRequestData('POST', [], ['param1' => [ 'name' => '', @@ -85,16 +84,17 @@ public function testConvertEmptyUploadedFilesToNull() 'size' => 0, ]]); - $form->expects($this->once()) - ->method('submit') - ->with($this->identicalTo(null)); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($form->isSubmitted()); + $this->assertNull($form->getData()); } public function testFixBuggyFilesArray() { - $form = $this->getMockForm('param1', 'POST', false); + $form = $this->createForm('param1', 'POST', true); + $fieldForm = $this->createBuilder('field', false, ['allow_file_upload' => true])->getForm(); + $form->add($fieldForm); $this->setRequestData('POST', [], ['param1' => [ 'name' => [ @@ -114,24 +114,25 @@ public function testFixBuggyFilesArray() ], ]]); - $form->expects($this->once()) - ->method('submit') - ->with([ - 'field' => [ - 'name' => 'upload.txt', - 'type' => 'text/plain', - 'tmp_name' => 'owfdskjasdfsa', - 'error' => UPLOAD_ERR_OK, - 'size' => 100, - ], - ]); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($form->isSubmitted()); + $this->assertEquals([ + 'name' => 'upload.txt', + 'type' => 'text/plain', + 'tmp_name' => 'owfdskjasdfsa', + 'error' => UPLOAD_ERR_OK, + 'size' => 100, + ], $fieldForm->getData()); } public function testFixBuggyNestedFilesArray() { - $form = $this->getMockForm('param1', 'POST'); + $form = $this->createForm('param1', 'POST', true); + $fieldForm = $this->createForm('field', null, true); + $form->add($fieldForm); + $subfieldForm = $this->createBuilder('subfield', false, ['allow_file_upload' => true])->getForm(); + $fieldForm->add($subfieldForm); $this->setRequestData('POST', [], ['param1' => [ 'name' => [ @@ -151,26 +152,21 @@ public function testFixBuggyNestedFilesArray() ], ]]); - $form->expects($this->once()) - ->method('submit') - ->with([ - 'field' => [ - 'subfield' => [ - 'name' => 'upload.txt', - 'type' => 'text/plain', - 'tmp_name' => 'owfdskjasdfsa', - 'error' => UPLOAD_ERR_OK, - 'size' => 100, - ], - ], - ]); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertTrue($subfieldForm->isSubmitted()); + $this->assertEquals([ + 'name' => 'upload.txt', + 'type' => 'text/plain', + 'tmp_name' => 'owfdskjasdfsa', + 'error' => UPLOAD_ERR_OK, + 'size' => 100, + ], $subfieldForm->getData()); } public function testMethodOverrideHeaderIgnoredIfNotPost() { - $form = $this->getMockForm('param1', 'POST'); + $form = $this->createForm('param1', 'POST'); $this->setRequestData('GET', [ 'param1' => 'DATA', @@ -178,10 +174,9 @@ public function testMethodOverrideHeaderIgnoredIfNotPost() $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT'; - $form->expects($this->never()) - ->method('submit'); - $this->requestHandler->handleRequest($form, $this->request); + + $this->assertFalse($form->isSubmitted()); } protected function setRequestData($method, $data, $files = []) diff --git a/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php b/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php index cdbb79ae3e0f..32bb8bb78871 100644 --- a/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php +++ b/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php @@ -12,6 +12,8 @@ namespace Symfony\Component\Form\Tests; use PHPUnit\Framework\TestCase; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormConfigInterface; use Symfony\Component\Form\FormTypeExtensionInterface; use Symfony\Component\Form\FormTypeInterface; use Symfony\Component\Form\ResolvedFormType; @@ -220,7 +222,7 @@ public function testBuildForm() public function testCreateView() { - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $view = $this->resolvedType->createView($form); @@ -230,7 +232,7 @@ public function testCreateView() public function testCreateViewWithParent() { - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $parentView = $this->getMockBuilder('Symfony\Component\Form\FormView')->getMock(); $view = $this->resolvedType->createView($form, $parentView); @@ -242,7 +244,7 @@ public function testCreateViewWithParent() public function testBuildView() { $options = ['a' => '1', 'b' => '2']; - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $view = $this->getMockBuilder('Symfony\Component\Form\FormView')->getMock(); $i = 0; @@ -284,7 +286,7 @@ public function testBuildView() public function testFinishView() { $options = ['a' => '1', 'b' => '2']; - $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock()); $view = $this->getMockBuilder('Symfony\Component\Form\FormView')->getMock(); $i = 0; diff --git a/src/Symfony/Component/Form/Tests/SimpleFormTest.php b/src/Symfony/Component/Form/Tests/SimpleFormTest.php index ebc2ee03641c..214ff3beab24 100644 --- a/src/Symfony/Component/Form/Tests/SimpleFormTest.php +++ b/src/Symfony/Component/Form/Tests/SimpleFormTest.php @@ -218,14 +218,14 @@ public function getDisabledStates() public function testGetRootReturnsRootOfParent() { - $parent = $this->getMockForm(); - $parent->expects($this->once()) - ->method('getRoot') - ->will($this->returnValue('ROOT')); + $root = $this->createForm(); + + $parent = $this->createForm(); + $parent->setParent($root); $this->form->setParent($parent); - $this->assertEquals('ROOT', $this->form->getRoot()); + $this->assertSame($root, $this->form->getRoot()); } public function testGetRootReturnsSelfIfNoParent() @@ -720,12 +720,13 @@ public function testCreateViewWithParent() { $type = $this->getMockBuilder('Symfony\Component\Form\ResolvedFormTypeInterface')->getMock(); $view = $this->getMockBuilder('Symfony\Component\Form\FormView')->getMock(); - $parentForm = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock(); + $parentType = $this->getMockBuilder('Symfony\Component\Form\ResolvedFormTypeInterface')->getMock(); + $parentForm = $this->getBuilder()->setType($parentType)->getForm(); $parentView = $this->getMockBuilder('Symfony\Component\Form\FormView')->getMock(); $form = $this->getBuilder()->setType($type)->getForm(); $form->setParent($parentForm); - $parentForm->expects($this->once()) + $parentType->expects($this->once()) ->method('createView') ->will($this->returnValue($parentView)); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/ClassMetadataTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/ClassMetadataTest.php index f62967935dc5..636d8a8ab891 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/ClassMetadataTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/ClassMetadataTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Serializer\Tests\Mapping; use PHPUnit\Framework\TestCase; +use Symfony\Component\Serializer\Mapping\AttributeMetadata; use Symfony\Component\Serializer\Mapping\ClassMetadata; /** @@ -29,11 +30,8 @@ public function testAttributeMetadata() { $classMetadata = new ClassMetadata('c'); - $a1 = $this->getMockBuilder('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface')->getMock(); - $a1->method('getName')->willReturn('a1'); - - $a2 = $this->getMockBuilder('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface')->getMock(); - $a2->method('getName')->willReturn('a2'); + $a1 = new AttributeMetadata('a1'); + $a2 = new AttributeMetadata('a2'); $classMetadata->addAttributeMetadata($a1); $classMetadata->addAttributeMetadata($a2); @@ -46,33 +44,28 @@ public function testMerge() $classMetadata1 = new ClassMetadata('c1'); $classMetadata2 = new ClassMetadata('c2'); - $ac1 = $this->getMockBuilder('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface')->getMock(); - $ac1->method('getName')->willReturn('a1'); - $ac1->method('getGroups')->willReturn(['a', 'b']); - - $ac2 = $this->getMockBuilder('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface')->getMock(); - $ac2->method('getName')->willReturn('a1'); - $ac2->method('getGroups')->willReturn(['b', 'c']); + $ac1 = new AttributeMetadata('a1'); + $ac1->addGroup('a'); + $ac1->addGroup('b'); + $ac2 = new AttributeMetadata('a1'); + $ac2->addGroup('b'); + $ac2->addGroup('c'); $classMetadata1->addAttributeMetadata($ac1); $classMetadata2->addAttributeMetadata($ac2); $classMetadata1->merge($classMetadata2); - $ac1->method('getGroups')->willReturn('a', 'b', 'c'); - - $this->assertEquals(['a1' => $ac1], $classMetadata2->getAttributesMetadata()); + $this->assertSame(['a', 'b', 'c'], $ac1->getGroups()); + $this->assertEquals(['a1' => $ac1], $classMetadata1->getAttributesMetadata()); } public function testSerialize() { $classMetadata = new ClassMetadata('a'); - $a1 = $this->getMockBuilder('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface')->getMock(); - $a1->method('getName')->willReturn('b1'); - - $a2 = $this->getMockBuilder('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface')->getMock(); - $a2->method('getName')->willReturn('b2'); + $a1 = new AttributeMetadata('b1'); + $a2 = new AttributeMetadata('b2'); $classMetadata->addAttributeMetadata($a1); $classMetadata->addAttributeMetadata($a2); diff --git a/src/Symfony/Component/Validator/Tests/Validator/TraceableValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/TraceableValidatorTest.php index 3d89f4e14238..b80efed27e7b 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/TraceableValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/TraceableValidatorTest.php @@ -15,7 +15,6 @@ use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; -use Symfony\Component\Validator\ConstraintViolationListInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Mapping\MetadataInterface; use Symfony\Component\Validator\Validator\ContextualValidatorInterface; @@ -87,13 +86,13 @@ public function testForwardsToOriginalValidator() $expects('startContext')->willReturn($expected = $this->createMock(ContextualValidatorInterface::class)); $this->assertSame($expected, $validator->startContext(), 'returns original validator startContext() result'); - $expects('validate')->willReturn($expected = $this->createMock(ConstraintViolationListInterface::class)); + $expects('validate')->willReturn($expected = new ConstraintViolationList()); $this->assertSame($expected, $validator->validate('value'), 'returns original validator validate() result'); - $expects('validateProperty')->willReturn($expected = $this->createMock(ConstraintViolationListInterface::class)); + $expects('validateProperty')->willReturn($expected = new ConstraintViolationList()); $this->assertSame($expected, $validator->validateProperty(new \stdClass(), 'property'), 'returns original validator validateProperty() result'); - $expects('validatePropertyValue')->willReturn($expected = $this->createMock(ConstraintViolationListInterface::class)); + $expects('validatePropertyValue')->willReturn($expected = new ConstraintViolationList()); $this->assertSame($expected, $validator->validatePropertyValue(new \stdClass(), 'property', 'value'), 'returns original validator validatePropertyValue() result'); } From df73ebf00f4a1ac26e13a7187a6dd32836e0328f Mon Sep 17 00:00:00 2001 From: Stadly Date: Wed, 23 Jan 2019 11:01:37 +0100 Subject: [PATCH 08/11] [Translation] Concatenated translation messages --- .../Translation/Extractor/PhpExtractor.php | 22 ++++++++++++++----- .../Tests/Extractor/PhpExtractorTest.php | 1 + .../fixtures/extractor/translation.html.php | 8 +++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php index bf7da431a7f1..7f4c6e60394c 100644 --- a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php +++ b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php @@ -156,9 +156,14 @@ private function getValue(\Iterator $tokenIterator) { $message = ''; $docToken = ''; + $docPart = ''; for (; $tokenIterator->valid(); $tokenIterator->next()) { $t = $tokenIterator->current(); + if ('.' === $t) { + // Concatenate with next token + continue; + } if (!isset($t[1])) { break; } @@ -169,19 +174,24 @@ private function getValue(\Iterator $tokenIterator) break; case T_ENCAPSED_AND_WHITESPACE: case T_CONSTANT_ENCAPSED_STRING: - $message .= $t[1]; + if ('' === $docToken) { + $message .= PhpStringTokenParser::parse($t[1]); + } else { + $docPart = $t[1]; + } break; case T_END_HEREDOC: - return PhpStringTokenParser::parseDocString($docToken, $message); + $message .= PhpStringTokenParser::parseDocString($docToken, $docPart); + $docToken = ''; + $docPart = ''; + break; + case T_WHITESPACE: + break; default: break 2; } } - if ($message) { - $message = PhpStringTokenParser::parse($message); - } - return $message; } diff --git a/src/Symfony/Component/Translation/Tests/Extractor/PhpExtractorTest.php b/src/Symfony/Component/Translation/Tests/Extractor/PhpExtractorTest.php index f6a17d00c0f6..73ccb07cfb07 100644 --- a/src/Symfony/Component/Translation/Tests/Extractor/PhpExtractorTest.php +++ b/src/Symfony/Component/Translation/Tests/Extractor/PhpExtractorTest.php @@ -51,6 +51,7 @@ public function testExtraction($resource) $expectedHeredoc => 'prefix'.$expectedHeredoc, $expectedNowdoc => 'prefix'.$expectedNowdoc, '{0} There is no apples|{1} There is one apple|]1,Inf[ There are %count% apples' => 'prefix{0} There is no apples|{1} There is one apple|]1,Inf[ There are %count% apples', + 'concatenated message with heredoc and nowdoc' => 'prefixconcatenated message with heredoc and nowdoc', ], 'not_messages' => [ 'other-domain-test-no-params-short-array' => 'prefixother-domain-test-no-params-short-array', diff --git a/src/Symfony/Component/Translation/Tests/fixtures/extractor/translation.html.php b/src/Symfony/Component/Translation/Tests/fixtures/extractor/translation.html.php index 11261311a1be..094660335272 100644 --- a/src/Symfony/Component/Translation/Tests/fixtures/extractor/translation.html.php +++ b/src/Symfony/Component/Translation/Tests/fixtures/extractor/translation.html.php @@ -32,6 +32,14 @@ ['%count%' => 10] ); ?> +trans('concatenated'.' message'.<< + trans('other-domain-test-no-params-short-array', [], 'not_messages'); ?> trans('other-domain-test-no-params-long-array', [], 'not_messages'); ?> From 81d3716b0d8e29f4268208383d8321f19f0d13e5 Mon Sep 17 00:00:00 2001 From: Alex Teterin <7018407@gmail.com> Date: Wed, 16 Jan 2019 10:26:23 +0300 Subject: [PATCH 09/11] [Cache] PDO-based cache pool table autocreation does not work --- .../Component/Cache/Traits/PdoTrait.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Cache/Traits/PdoTrait.php b/src/Symfony/Component/Cache/Traits/PdoTrait.php index 9917bd91f545..6d896fd55514 100644 --- a/src/Symfony/Component/Cache/Traits/PdoTrait.php +++ b/src/Symfony/Component/Cache/Traits/PdoTrait.php @@ -306,14 +306,7 @@ protected function doSave(array $values, $lifetime) $now = time(); $lifetime = $lifetime ?: null; - try { - $stmt = $conn->prepare($sql); - } catch (TableNotFoundException $e) { - if (!$conn->isTransactionActive() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) { - $this->createTable(); - } - $stmt = $conn->prepare($sql); - } + $stmt = $conn->prepare($sql); if ('sqlsrv' === $driver || 'oci' === $driver) { $stmt->bindParam(1, $id); @@ -340,8 +333,14 @@ protected function doSave(array $values, $lifetime) } foreach ($values as $id => $data) { - $stmt->execute(); - + try { + $stmt->execute(); + } catch (TableNotFoundException $e) { + if (!$conn->isTransactionActive() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) { + $this->createTable(); + } + $stmt->execute(); + } if (null === $driver && !$stmt->rowCount()) { try { $insertStmt->execute(); From a0a7400d6f5405d24529a12c77d27cb48c8b5534 Mon Sep 17 00:00:00 2001 From: James Hudson Date: Fri, 11 Jan 2019 07:38:02 +0000 Subject: [PATCH 10/11] [Console] Fixed #29835: ConfirmationQuestion with default true for answer '0' --- .../Console/Question/ConfirmationQuestion.php | 2 +- .../Question/ConfirmationQuestionTest.php | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Console/Tests/Question/ConfirmationQuestionTest.php diff --git a/src/Symfony/Component/Console/Question/ConfirmationQuestion.php b/src/Symfony/Component/Console/Question/ConfirmationQuestion.php index 150ab27f303b..d871fb8a79b0 100644 --- a/src/Symfony/Component/Console/Question/ConfirmationQuestion.php +++ b/src/Symfony/Component/Console/Question/ConfirmationQuestion.php @@ -53,7 +53,7 @@ private function getDefaultNormalizer() return $answer && $answerIsTrue; } - return !$answer || $answerIsTrue; + return '' === $answer || $answerIsTrue; }; } } diff --git a/src/Symfony/Component/Console/Tests/Question/ConfirmationQuestionTest.php b/src/Symfony/Component/Console/Tests/Question/ConfirmationQuestionTest.php new file mode 100644 index 000000000000..83899772a82d --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Question/ConfirmationQuestionTest.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Question; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Question\ConfirmationQuestion; + +class ConfirmationQuestionTest extends TestCase +{ + /** + * @dataProvider normalizerUsecases + */ + public function testDefaultRegexUsecases($default, $answers, $expected, $message) + { + $sut = new ConfirmationQuestion('A question', $default); + + foreach ($answers as $answer) { + $normalizer = $sut->getNormalizer(); + $actual = $normalizer($answer); + $this->assertEquals($expected, $actual, sprintf($message, $answer)); + } + } + + public function normalizerUsecases() + { + return [ + [ + true, + ['y', 'Y', 'yes', 'YES', 'yEs', ''], + true, + 'When default is true, the normalizer must return true for "%s"', + ], + [ + true, + ['n', 'N', 'no', 'NO', 'nO', 'foo', '1', '0'], + false, + 'When default is true, the normalizer must return false for "%s"', + ], + [ + false, + ['y', 'Y', 'yes', 'YES', 'yEs'], + true, + 'When default is false, the normalizer must return true for "%s"', + ], + [ + false, + ['n', 'N', 'no', 'NO', 'nO', 'foo', '1', '0', ''], + false, + 'When default is false, the normalizer must return false for "%s"', + ], + ]; + } +} From 1954187fac1e5d4ffa10d1ab66ad74f4d8a22e50 Mon Sep 17 00:00:00 2001 From: adam-mospan Date: Thu, 3 Jan 2019 17:40:56 +0200 Subject: [PATCH 11/11] [HttpFoundation] Check file exists before unlink --- src/Symfony/Component/HttpFoundation/BinaryFileResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index 557577a1ed6c..cf648dfe9d54 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -305,7 +305,7 @@ public function sendContent() fclose($out); fclose($file); - if ($this->deleteFileAfterSend) { + if ($this->deleteFileAfterSend && file_exists($this->file->getPathname())) { unlink($this->file->getPathname()); }