diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php index fd1c319a6310..7d063614e7a2 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php @@ -2422,13 +2422,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 bc3595800181..025928502934 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -24,7 +24,7 @@ "symfony/asset": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0", "symfony/finder": "~3.4|~4.0", - "symfony/form": "^4.2", + "symfony/form": "^4.2.3", "symfony/http-foundation": "~3.4|~4.0", "symfony/http-kernel": "~3.4|~4.0", "symfony/polyfill-intl-icu": "~1.0", diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php index 9890ce4da46b..8bd22bed79ca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php @@ -16,6 +16,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; @@ -488,8 +489,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/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 9b7f8355e5dd..e18554972e42 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -40,7 +40,7 @@ "symfony/dom-crawler": "~3.4|~4.0", "symfony/polyfill-intl-icu": "~1.0", "symfony/security": "~3.4|~4.0", - "symfony/form": "^4.2", + "symfony/form": "^4.2.3", "symfony/expression-language": "~3.4|~4.0", "symfony/messenger": "^4.2", "symfony/process": "~3.4|~4.0", diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php index fbdb975745c6..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,24 @@ public function testGetNameValidTemplate() ->withAnyParameters() ->will($this->returnCallback([$this, 'profilerHasCallback'])); - $profile = $this->mockProfile(); - $profile->expects($this->any()) - ->method('hasCollector') + $this->assertEquals('FooBundle:Collector:foo.html.twig', $this->templateManager->getName(new ProfileDummy(), 'foo')); + } + + /** + * template should be loaded for 'foo' because other collectors are + * missing in profile or in profiler. + */ + public function testGetTemplates() + { + $this->profiler->expects($this->any()) + ->method('has') + ->withAnyParameters() ->will($this->returnCallback([$this, 'profileHasCollectorCallback'])); - $this->assertEquals('FooBundle:Collector:foo.html.twig', $this->templateManager->getName($profile, 'foo')); + $result = $this->templateManager->getTemplates(new ProfileDummy()); + $this->assertArrayHasKey('foo', $result); + $this->assertArrayNotHasKey('bar', $result); + $this->assertArrayNotHasKey('baz', $result); } public function profilerHasCallback($panel) @@ -133,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/Console/Question/ConfirmationQuestion.php b/src/Symfony/Component/Console/Question/ConfirmationQuestion.php index 26eea6a136b7..88227dfa6313 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"', + ], + ]; + } +} diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index efbfa5bcaa52..b47e40211643 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -496,6 +496,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 069796cddb9a..f3205840550c 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(); } public function testHandleException() @@ -501,4 +506,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 @@ +vars['attr']['inputmode'] = 'url'; + $view->vars['type'] = 'text'; + } + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 11056ae42583..fb0ba683e82e 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/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index f8997d546e64..ab03646bbb33 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -2236,10 +2236,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 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 981e9609cece..aa3268c262f6 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() @@ -925,12 +919,24 @@ public function testClearErrorsDeep() 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) @@ -957,24 +963,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() @@ -1067,7 +1057,7 @@ public function testDisabledButtonIsNotSubmitted() ->getForm(); $form = $this->createForm() - ->add($this->getBuilder('text')->getForm()) + ->add($this->createForm('text', false)) ->add($submit) ; @@ -1112,11 +1102,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 8c8ba330816a..3b8afe415e37 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() @@ -711,12 +711,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/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index 0f5c9bb6707b..115f486f023f 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -300,7 +300,7 @@ public function sendContent() fclose($out); fclose($file); - if ($this->deleteFileAfterSend) { + if ($this->deleteFileAfterSend && file_exists($this->file->getPathname())) { unlink($this->file->getPathname()); } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php index 3c3e3b2d22a7..1db590b36078 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 = []) */ 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 e150aae517f9..5c72a89aa551 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php @@ -59,6 +59,12 @@ public function testOpenSession() public function testCloseSession() { + $this->memcached + ->expects($this->once()) + ->method('quit') + ->will($this->returnValue(true)) + ; + $this->assertTrue($this->storage->close()); } diff --git a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php index 54e41431e0ce..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,6 +42,7 @@ 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 = []); diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php index 09aca60ff23e..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,6 +36,7 @@ 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 = []); 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/Translation/Extractor/PhpExtractor.php b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php index a934653c33d0..5f6aecd50a2a 100644 --- a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php +++ b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php @@ -154,9 +154,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; } @@ -167,19 +172,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 bf794c45ad7d..55520203c6cb 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'); ?> 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'); }