Skip to content

Commit

Permalink
Merge branch '4.2'
Browse files Browse the repository at this point in the history
* 4.2:
  [HttpFoundation] Check file exists before unlink
  [Console] Fixed #29835: ConfirmationQuestion with default true for answer '0'
  [Cache] PDO-based cache pool table autocreation does not work
  [Translation] Concatenated translation messages
  [Form] ensure compatibility with older PHPUnit mocks
  [Serializer] Docblock about throwing exceptions on serializer
  [Cache] fix used variable name
  [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
  Always pass $key to NullAdapter->createCacheItem
  • Loading branch information
nicolas-grekas committed Jan 25, 2019
2 parents cd4b031 + 62c595a commit 4edfbb5
Show file tree
Hide file tree
Showing 42 changed files with 595 additions and 363 deletions.
Expand Up @@ -2505,13 +2505,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
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
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;
}
}
}
2 changes: 1 addition & 1 deletion src/Symfony/Component/Cache/Adapter/NullAdapter.php
Expand Up @@ -42,7 +42,7 @@ function ($key) {
*/
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
{
return $callback(($this->createCacheItem)());
return $callback(($this->createCacheItem)($key));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Cache/Simple/Psr6Cache.php
Expand Up @@ -154,7 +154,7 @@ public function getMultiple($keys, $default = null)
$values[$key] = $item->isHit() ? $item->get() : $default;
}

return $value;
return $values;
}

foreach ($items as $key => $item) {
Expand Down
13 changes: 13 additions & 0 deletions src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php
Expand Up @@ -34,6 +34,19 @@ public function testGetItem()
$this->assertNull($item->get(), "Item's value must be null when isHit is false.");
}

public function testGet()
{
$adapter = $this->createCachePool();

$fetched = [];
$item = $adapter->get('myKey', function ($item) use (&$fetched) { $fetched[] = $item; });
$this->assertCount(1, $fetched);
$item = $fetched[0];
$this->assertFalse($item->isHit());
$this->assertNull($item->get(), "Item's value must be null when isHit is false.");
$this->assertSame('myKey', $item->getKey());
}

public function testHasItem()
{
$this->assertFalse($this->createCachePool()->hasItem('key'));
Expand Down
Expand Up @@ -24,9 +24,9 @@ class ExternalAdapter implements CacheItemPoolInterface
{
private $cache;

public function __construct()
public function __construct(int $defaultLifetime = 0)
{
$this->cache = new ArrayAdapter();
$this->cache = new ArrayAdapter($defaultLifetime);
}

public function getItem($key)
Expand Down
10 changes: 4 additions & 6 deletions src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php
Expand Up @@ -11,20 +11,18 @@

namespace Symfony\Component\Cache\Tests\Simple;

use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Simple\Psr6Cache;

/**
* @group time-sensitive
*/
class Psr6CacheTest extends CacheTestCase
abstract class Psr6CacheTest extends CacheTestCase
{
protected $skippedTests = [
'testPrune' => 'Psr6Cache just proxies',
];

public function createSimpleCache($defaultLifetime = 0)
{
return new Psr6Cache(new FilesystemAdapter('', $defaultLifetime));
return new Psr6Cache($this->createCacheItemPool($defaultLifetime));
}

abstract protected function createCacheItemPool($defaultLifetime = 0);
}
@@ -0,0 +1,25 @@
<?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\Cache\Tests\Simple;

use Symfony\Component\Cache\Adapter\FilesystemAdapter;

/**
* @group time-sensitive
*/
class Psr6CacheWithAdapterTest extends Psr6CacheTest
{
protected function createCacheItemPool($defaultLifetime = 0)
{
return new FilesystemAdapter('', $defaultLifetime);
}
}
@@ -0,0 +1,25 @@
<?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\Cache\Tests\Simple;

use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;

/**
* @group time-sensitive
*/
class Psr6CacheWithoutAdapterTest extends Psr6CacheTest
{
protected function createCacheItemPool($defaultLifetime = 0)
{
return new ExternalAdapter($defaultLifetime);
}
}
19 changes: 9 additions & 10 deletions src/Symfony/Component/Cache/Traits/PdoTrait.php
Expand Up @@ -306,14 +306,7 @@ protected function doSave(array $values, $lifetime)

$now = time();
$lifetime = $lifetime ?: null;
try {
$stmt = $conn->prepare($sql);
} catch (TableNotFoundException $e) {
if (!$conn->isTransactionActive() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
$this->createTable();
}
$stmt = $conn->prepare($sql);
}
$stmt = $conn->prepare($sql);

if ('sqlsrv' === $driver || 'oci' === $driver) {
$stmt->bindParam(1, $id);
Expand All @@ -340,8 +333,14 @@ protected function doSave(array $values, $lifetime)
}

foreach ($values as $id => $data) {
$stmt->execute();

try {
$stmt->execute();
} catch (TableNotFoundException $e) {
if (!$conn->isTransactionActive() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
$this->createTable();
}
$stmt->execute();
}
if (null === $driver && !$stmt->rowCount()) {
try {
$insertStmt->execute();
Expand Down
Expand Up @@ -53,7 +53,7 @@ private function getDefaultNormalizer()
return $answer && $answerIsTrue;
}

return !$answer || $answerIsTrue;
return '' === $answer || $answerIsTrue;
};
}
}
@@ -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
Expand Up @@ -498,6 +498,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

0 comments on commit 4edfbb5

Please sign in to comment.