10000 Merge branch '3.4' into 4.1 · symfony/symfony@02fe23d · GitHub
[go: up one dir, main page]

Skip to content

Commit 02fe23d

Browse files
Merge branch '3.4' into 4.1
* 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
2 parents 343d24d + afb7bb5 commit 02fe23d

36 files changed

+517
-345
lines changed

src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2402,13 +2402,29 @@ public function testTimezoneWithPlaceholder()
24022402
);
24032403
}
24042404

2405-
public function testUrl()
2405+
public function testUrlWithDefaultProtocol()
24062406
{
24072407
$url = 'http://www.google.com?foo1=bar1&foo2=bar2';
2408-
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url);
2408+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']);
24092409

24102410
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
24112411
'/input
2412+
[@type="text"]
2413+
[@name="name"]
2414+
[@class="my&class form-control"]
2415+
[@value="http://www.google.com?foo1=bar1&foo2=bar2"]
2416+
[@inputmode="url"]
2417+
'
2418+
);
2419+
}
2420+
2421+
public function testUrlWithoutDefaultProtocol()
2422+
{
2423+
$url = 'http://www.google.com?foo1=bar1&foo2=bar2';
2424+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]);
2425+
2426+
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
2427+
'/input
24122428
[@type="url"]
24132429
[@name="name"]
24142430
[@class="my&class form-control"]

src/Symfony/Bridge/Twig/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"symfony/asset": "~3.4|~4.0",
2424
"symfony/dependency-injection": "~3.4|~4.0",
2525
"symfony/finder": "~3.4|~4.0",
26-
"symfony/form": "^4.1.5",
26+
"symfony/form": "^4.1.11|^4.2.3",
2727
"symfony/http-foundation": "~3.4|~4.0",
2828
"symfony/http-kernel": "~3.4|~4.0",
2929
"symfony/polyfill-intl-icu": "~1.0",

src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
1616
use Symfony\Component\DependencyInjection\Container;
1717
use Symfony\Component\Form\Form;
18+
use Symfony\Component\Form\FormConfigInterface;
1819
use Symfony\Component\HttpFoundation\BinaryFileResponse;
1920
use Symfony\Component\HttpFoundation\File\File;
2021
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -487,8 +488,7 @@ public function testCreateNotFoundException()
487488

488489
public function testCreateForm()
489490
{
490-
$config = $this->getMockBuilder('Symfony\Component\Form\FormConfigInterface')->getMock();
491-
$form = new Form($config);
491+
$form = new Form($this->getMockBuilder(FormConfigInterface::class)->getMock());
492492

493493
$formFactory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
494494
$formFactory->expects($this->once())->method('create')->willReturn($form);

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"symfony/dom-crawler": "~3.4|~4.0",
4040
"symfony/polyfill-intl-icu": "~1.0",
4141
"symfony/security": "~3.4|~4.0",
42-
"symfony/form": "^4.1",
42+
"symfony/form": "^4.1.11|^4.2.3",
4343
"symfony/expression-language": "~3.4|~4.0",
4444
"symfony/messenger": "^4.1",
4545
"symfony/process": "~3.4|~4.0",

src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Bundle\WebProfilerBundle\Profiler\TemplateManager;
1515
use Symfony\Bundle\WebProfilerBundle\Tests\TestCase;
16+
use Symfony\Component\HttpKernel\Profiler\Profile;
1617
use Twig\Environment;
1718

1819
/**
@@ -57,8 +58,7 @@ protected function setUp()
5758
*/
5859
public function testGetNameOfInvalidTemplate()
5960
{
60-
$profile = $this->mockProfile();
61-
$this->templateManager->getName($profile, 'notexistingpanel');
61+
$this->templateManager->getName(new Profile('token'), 'notexistingpanel');
6262
}
6363

6464
/**
@@ -71,12 +71,24 @@ public function testGetNameValidTemplate()
7171
->withAnyParameters()
7272
->will($this->returnCallback([$this, 'profilerHasCallback']));
7373

74-
$profile = $this->mockProfile();
75-
$profile->expects($this->any())
76-
->method('hasCollector')
74+
$this->assertEquals('FooBundle:Collector:foo.html.twig', $this->templateManager->getName(new ProfileDummy(), 'foo'));
75+
}
76+
77+
/**
78+
* template should be loaded for 'foo' because other collectors are
79+
* missing in profile or in profiler.
80+
*/
81+
public function testGetTemplates()
82+
{
83+
$this->profiler->expects($this->any())
84+
->method('has')
85+
->withAnyParameters()
7786
->will($this->returnCallback([$this, 'profileHasCollectorCallback']));
7887

79-
$this->assertEquals('FooBundle:Collector:foo.html.twig', $this->templateManager->getName($profile, 'foo'));
88+
$result = $this->templateManager->getTemplates(new ProfileDummy());
89+
$this->assertArrayHasKey('foo', $result);
90+
$this->assertArrayNotHasKey('bar', $result);
91+
$this->assertArrayNotHasKey('baz', $result);
8092
}
8193

8294
public function profilerHasCallback($panel)
@@ -133,3 +145,22 @@ protected function mockProfiler()
133145
return $this->profiler;
134146
}
135147
}
148+
149+
class ProfileDummy extends Profile
150+
{
151+
public function __construct()
152+
{
153+
parent::__construct('token');
154+
}
155+
156+
public function hasCollector($name)
157+
{
158+
switch ($name) {
159+
case 'foo':
160+
case 'bar':
161+
return true;
162+
default:
163+
return false;
164+
}
165+
}
166+
}

src/Symfony/Component/Console/Question/ConfirmationQuestion.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ private function getDefaultNormalizer()
5353
return $answer && $answerIsTrue;
5454
}
5555

56-
return !$answer || $answerIsTrue;
56+
return '' === $answer || $answerIsTrue;
5757
};
5858
}
5959
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Console\Tests\Question;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Console\Question\ConfirmationQuestion;
16+
17+
class ConfirmationQuestionTest extends TestCase
18+
{
19+
/**
20+
* @dataProvider normalizerUsecases
21+
*/
22+
public function testDefaultRegexUsecases($default, $answers, $expected, $message)
23+
{
24+
$sut = new ConfirmationQuestion('A question', $default);
25+
26+
foreach ($answers as $answer) {
27+
$normalizer = $sut->getNormalizer();
28+
$actual = $normalizer($answer);
29+
$this->assertEquals($expected, $actual, sprintf($message, $answer));
30+
}
31+
}
32+
33+
public function normalizerUsecases()
34+
{
35+
return [
36+
[
37+
true,
38+
['y', 'Y', 'yes', 'YES', 'yEs', ''],
39+
true,
40+
'When default is true, the normalizer must return true for "%s"',
41+
],
42+
[
43+
true,
44+
['n', 'N', 'no', 'NO', 'nO', 'foo', '1', '0'],
45+
false,
46+
'When default is true, the normalizer must return false for "%s"',
47+
],
48+
[
49+
false,
50+
['y', 'Y', 'yes', 'YES', 'yEs'],
51+
true,
52+
'When default is false, the normalizer must return true for "%s"',
53+
],
54+
[
55+
false,
56+
['n', 'N', 'no', 'NO', 'nO', 'foo', '1', '0', ''],
57+
false,
58+
'When default is false, the normalizer must return false for "%s"',
59+
],
60+
];
61+
}
62+
}

src/Symfony/Component/Debug/ErrorHandler.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,10 @@ public function handleError($type, $message, $file, $line)
492492
$this->loggers[$type][0]->log($level, $logMessage, $errorAsException ? ['exception' => $errorAsException] : []);
493493
} finally {
494494
$this->isRecursive = false;
495+
496+
if (!\defined('HHVM_VERSION')) {
497+
set_error_handler([$this, __FUNCTION__]);
498+
}
495499
}
496500
}
497501

src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
namespace Symfony\Component\Debug\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Psr\Log\LoggerInterface;
1516
use Psr\Log\LogLevel;
17+
use Psr\Log\NullLogger;
1618
use Symfony\Component\Debug\BufferingLogger;
1719
use Symfony\Component\Debug\ErrorHandler;
1820
use Symfony\Component\Debug\Exception\SilencedErrorContext;
21+
use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler;
1922

2023
/**
2124
* ErrorHandlerTest.
@@ -321,6 +324,8 @@ public function testHandleDeprecation()
321324
$handler = new ErrorHandler();
322325
$handler->setDefaultLogger($logger);
323326
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
327+
328+
restore_error_handler();
324329
}
325330

326331
public function testHandleException()
@@ -501,4 +506,43 @@ public function testCustomExceptionHandler()
501506

502507
$handler->handleException(new \Exception());
503508
}
509+
510+
/**
511+
* @dataProvider errorHandlerIsNotLostWhenLoggingProvider
512+
*/
513+
public function testErrorHandlerIsNotLostWhenLogging($customErrorHandlerHasBeenPreviouslyDefined, LoggerInterface $logger)
514+
{
515+
try {
516+
if ($customErrorHandlerHasBeenPreviouslyDefined) {
517+
set_error_handler('count');
518+
}
519+
520+
$handler = ErrorHandler::register();
521+
$handler->setDefaultLogger($logger);
522+
523+
@trigger_error('foo', E_USER_DEPRECATED);
524+
@trigger_error('bar', E_USER_DEPRECATED);
525+
526+
$this->assertSame([$handler, 'handleError'], set_error_handler('var_dump'));
527+
528+
restore_error_handler();
529+
530+
if ($customErrorHandlerHasBeenPreviouslyDefined) {
531+
restore_error_handler();
532+
}
533+
} finally {
534+
restore_error_handler();
535+
restore_exception_handler();
536+
}
537+
}
538+
539+
public function errorHandlerIsNotLostWhenLoggingProvider()
540+
{
541+
return [
542+
[false, new NullLogger()],
543+
[true, new NullLogger()],
544+
[false, new LoggerThatSetAnErrorHandler()],
545+
[true, new LoggerThatSetAnErrorHandler()],
546+
];
547+
}
504548
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Symfony\Component\Debug\Tests\Fixtures;
4+
5+
use Psr\Log\AbstractLogger;
6+
7+
class LoggerThatSetAnErrorHandler extends AbstractLogger
8+
{
9+
public function log($level, $message, array $context = [])
10+
{
11+
set_error_handler('is_string');
12+
restore_error_handler();
13+
}
14+
}

src/Symfony/Component/Form/Extension/Core/Type/UrlType.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use Symfony\Component\Form\AbstractType;
1515
use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener;
1616
use Symfony\Component\Form\FormBuilderInterface;
17+
use Symfony\Component\Form\FormInterface;
18+
use Symfony\Component\Form\FormView;
1719
use Symfony\Component\OptionsResolver\OptionsResolver;
1820

1921
class UrlType extends AbstractType
@@ -28,6 +30,17 @@ public function buildForm(FormBuilderInterface $builder, array $options)
2830
}
2931
}
3032

33+
/**
34+
* {@inheritdoc}
35+
*/
36+
public function buildView(FormView $view, FormInterface $form, array $options)
37+
{
38+
if ($options['default_protocol']) {
39+
$view->vars['attr']['inputmode'] = 'url';
40+
$view->vars['type'] = 'text';
41+
}
42+
}
43+
3144
/**
3245
* {@inheritdoc}
3346
*/

src/Symfony/Component/Form/Form.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,11 @@ public function submit($submittedData, $clearMissing = true)
532532
$submittedData = null;
533533
} elseif (is_scalar($submittedData)) {
534534
$submittedData = (string) $submittedData;
535-
} elseif (!$this->config->getOption('allow_file_upload') && $this->config->getRequestHandler()->isFileUpload($submittedData)) {
536-
$submittedData = null;
537-
$this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, file upload given.');
535+
} elseif ($this->config->getRequestHandler()->isFileUpload($submittedData)) {
536+
if (!$this->config->getOption('allow_file_upload')) {
537+
$submittedData = null;
538+
$this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, file upload given.');
539+
}
538540
} elseif (\is_array($submittedData) && !$this->config->getCompound() && !$this->config->hasOption('multiple')) {
539541
$submittedData = null;
540542
$this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, array given.');

src/Symfony/Component/Form/Tests/AbstractFormTest.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,26 +65,6 @@ protected function getBuilder($name = 'name', EventDispatcherInterface $dispatch
6565
return new FormBuilder($name, $dataClass, $dispatcher ?: $this->dispatcher, $this->factory, $options);
6666
}
6767

68-
/**
69-
* @param string $name
70-
*
71-
* @return \PHPUnit_Framework_MockObject_MockObject
72-
*/
73-
protected function getMockForm($name = 'name')
74-
{
75-
$form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock();
76-
$config = $this->getMockBuilder('Symfony\Component\Form\FormConfigInterface')->getMock();
77-
78-
$form->expects($this->any())
79-
->method('getName')
80-
->will($this->returnValue($name));
81-
$form->expects($this->any())
82-
->method('getConfig')
83-
->will($this->returnValue($config));
84-
85-
return $form;
86-
}
87-
8868
/**
8969
* @return \PHPUnit_Framework_MockObject_MockObject
9070
*/

src/Symfony/Component/Form/Tests/AbstractLayoutTest.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,10 +2236,25 @@ public function testTimezoneWithPlaceholder()
22362236
);
22372237
}
22382238

2239-
public function testUrl()
2239+
public function testUrlWithDefaultProtocol()
22402240
{
22412241
$url = 'http://www.google.com?foo1=bar1&foo2=bar2';
2242-
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url);
2242+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']);
2243+
2244+
$this->assertWidgetMatchesXpath($form->createView(), [],
2245+
'/input
2246+
[@type="text"]
2247+
[@name="name"]
2248+
[@value="http://www.google.com?foo1=bar1&foo2=bar2"]
2249+
[@inputmode="url"]
2250+
'
2251+
);
2252+
}
2253+
2254+
public function testUrlWithoutDefaultProtocol()
2255+
{
2256+
$url = 'http://www.google.com?foo1=bar1&foo2=bar2';
2257+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]);
22432258

22442259
$this->assertWidgetMatchesXpath($form->createView(), [],
22452260
'/input

0 commit comments

Comments
 (0)
0