Skip to content

Commit

Permalink
Merge branch '3.4' into 4.1
Browse files Browse the repository at this point in the history
* 3.4:
  [HttpFoundation] Check file exists before unlink
  [Console] Fixed #29835: ConfirmationQuestion with default true for answer '0'
  [Translation] Concatenated translation messages
  [Form] ensure compatibility with older PHPUnit mocks
  [Serializer] Docblock about throwing exceptions on serializer
  [Debug][ErrorHandler] Preserve our error handler when a logger set another one
  [Form] Changed UrlType input type to text when default_protocol is not null
  [Bugfix] MemcachedSessionHandler::close() must close connection
  • Loading branch information
nicolas-grekas committed Jan 25, 2019
2 parents 343d24d + afb7bb5 commit 02fe23d
Show file tree
Hide file tree
Showing 36 changed files with 517 additions and 345 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2402,13 +2402,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"]
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bridge/Twig/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"symfony/asset": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/finder": "~3.4|~4.0",
"symfony/form": "^4.1.5",
"symfony/form": "^4.1.11|^4.2.3",
"symfony/http-foundation": "~3.4|~4.0",
"symfony/http-kernel": "~3.4|~4.0",
"symfony/polyfill-intl-icu": "~1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/FrameworkBundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"symfony/dom-crawler": "~3.4|~4.0",
"symfony/polyfill-intl-icu": "~1.0",
"symfony/security": "~3.4|~4.0",
"symfony/form": "^4.1",
"symfony/form": "^4.1.11|^4.2.3",
"symfony/expression-language": "~3.4|~4.0",
"symfony/messenger": "^4.1",
"symfony/process": "~3.4|~4.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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');
}

/**
Expand All @@ -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)
Expand Down Expand Up @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private function getDefaultNormalizer()
return $answer && $answerIsTrue;
}

return !$answer || $answerIsTrue;
return '' === $answer || $answerIsTrue;
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\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"',
],
];
}
}
4 changes: 4 additions & 0 deletions src/Symfony/Component/Debug/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,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__]);
}
}
}

Expand Down
44 changes: 44 additions & 0 deletions src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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()],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;

use Psr\Log\AbstractLogger;

class LoggerThatSetAnErrorHandler extends AbstractLogger
{
public function log($level, $message, array $context = [])
{
set_error_handler('is_string');
restore_error_handler();
}
}
13 changes: 13 additions & 0 deletions src/Symfony/Component/Form/Extension/Core/Type/UrlType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}
*/
Expand Down
8 changes: 5 additions & 3 deletions src/Symfony/Component/Form/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.');
Expand Down
20 changes: 0 additions & 20 deletions src/Symfony/Component/Form/Tests/AbstractFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
19 changes: 17 additions & 2 deletions src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 02fe23d

Please sign in to comment.