Merge branch '4.3' into 4.4

* 4.3:
  [4.3] Cleanup tests
  Cleanup tests
  [Finder] Prevent unintentional file locks in Windows
  [FrameworkBundle] Fix about command not showing .env vars
  [DomCrawler] Fix FileFormField PHPDoc
  [Mailer] Remove the default dispatcher in AbstractTransport
  Fix #33395 PHP 5.3 compatibility
This commit is contained in:
Nicolas Grekas 2019-09-02 16:51:55 +02:00
commit 727aa7ed9e
14 changed files with 60 additions and 81 deletions

View File

@ -319,7 +319,7 @@ class DeprecationErrorHandler
private static function getPhpUnitErrorHandler() private static function getPhpUnitErrorHandler()
{ {
if (!isset(self::$isAtLeastPhpUnit83)) { if (!isset(self::$isAtLeastPhpUnit83)) {
self::$isAtLeastPhpUnit83 = class_exists(ErrorHandler::class) && method_exists(ErrorHandler::class, '__invoke'); self::$isAtLeastPhpUnit83 = class_exists('PHPUnit\Util\ErrorHandler') && method_exists('PHPUnit\Util\ErrorHandler', '__invoke');
} }
if (!self::$isAtLeastPhpUnit83) { if (!self::$isAtLeastPhpUnit83) {
return 'PHPUnit\Util\ErrorHandler::handleError'; return 'PHPUnit\Util\ErrorHandler::handleError';

View File

@ -131,9 +131,9 @@ EOT
private static function getDotenvVars(): array private static function getDotenvVars(): array
{ {
$vars = []; $vars = [];
foreach (explode(',', getenv('SYMFONY_DOTENV_VARS')) as $name) { foreach (explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? $_ENV['SYMFONY_DOTENV_VARS'] ?? '') as $name) {
if ('' !== $name && false !== $value = getenv($name)) { if ('' !== $name && isset($_ENV[$name])) {
$vars[$name] = $value; $vars[$name] = $_ENV[$name];
} }
} }

View File

@ -23,8 +23,6 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
* to make real HTTP requests. * to make real HTTP requests.
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*
* @final
*/ */
class HttpBrowser extends AbstractBrowser class HttpBrowser extends AbstractBrowser
{ {
@ -32,7 +30,7 @@ class HttpBrowser extends AbstractBrowser
public function __construct(HttpClientInterface $client = null, History $history = null, CookieJar $cookieJar = null) public function __construct(HttpClientInterface $client = null, History $history = null, CookieJar $cookieJar = null)
{ {
if (!class_exists(HttpClient::class)) { if (!$client && !class_exists(HttpClient::class)) {
throw new \LogicException(sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__)); throw new \LogicException(sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__));
} }

View File

@ -113,7 +113,7 @@ class ChoiceFormField extends FormField
/** /**
* Sets the value of the field. * Sets the value of the field.
* *
* @param string|array $value The value of the field * @param string|array|bool $value The value of the field
* *
* @throws \InvalidArgumentException When value type provided is not correct * @throws \InvalidArgumentException When value type provided is not correct
*/ */

View File

@ -48,7 +48,7 @@ class FileFormField extends FormField
/** /**
* Sets the value of the field. * Sets the value of the field.
* *
* @param string $value The value of the field * @param string|null $value The value of the field
*/ */
public function setValue($value) public function setValue($value)
{ {

View File

@ -99,7 +99,7 @@ abstract class FormField
/** /**
* Sets the value of the field. * Sets the value of the field.
* *
* @param string $value The value of the field * @param string|array|bool|null $value The value of the field
*/ */
public function setValue($value) public function setValue($value)
{ {

View File

@ -41,15 +41,15 @@ class SortableIterator implements \IteratorAggregate
$order = $reverseOrder ? -1 : 1; $order = $reverseOrder ? -1 : 1;
if (self::SORT_BY_NAME === $sort) { if (self::SORT_BY_NAME === $sort) {
$this->sort = function ($a, $b) use ($order) { $this->sort = static function ($a, $b) use ($order) {
return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
}; };
} elseif (self::SORT_BY_NAME_NATURAL === $sort) { } elseif (self::SORT_BY_NAME_NATURAL === $sort) {
$this->sort = function ($a, $b) use ($order) { $this->sort = static function ($a, $b) use ($order) {
return $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); return $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
}; };
} elseif (self::SORT_BY_TYPE === $sort) { } elseif (self::SORT_BY_TYPE === $sort) {
$this->sort = function ($a, $b) use ($order) { $this->sort = static function ($a, $b) use ($order) {
if ($a->isDir() && $b->isFile()) { if ($a->isDir() && $b->isFile()) {
return -$order; return -$order;
} elseif ($a->isFile() && $b->isDir()) { } elseif ($a->isFile() && $b->isDir()) {
@ -59,15 +59,15 @@ class SortableIterator implements \IteratorAggregate
return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
}; };
} elseif (self::SORT_BY_ACCESSED_TIME === $sort) { } elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
$this->sort = function ($a, $b) use ($order) { $this->sort = static function ($a, $b) use ($order) {
return $order * ($a->getATime() - $b->getATime()); return $order * ($a->getATime() - $b->getATime());
}; };
} elseif (self::SORT_BY_CHANGED_TIME === $sort) { } elseif (self::SORT_BY_CHANGED_TIME === $sort) {
$this->sort = function ($a, $b) use ($order) { $this->sort = static function ($a, $b) use ($order) {
return $order * ($a->getCTime() - $b->getCTime()); return $order * ($a->getCTime() - $b->getCTime());
}; };
} elseif (self::SORT_BY_MODIFIED_TIME === $sort) { } elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
$this->sort = function ($a, $b) use ($order) { $this->sort = static function ($a, $b) use ($order) {
return $order * ($a->getMTime() - $b->getMTime()); return $order * ($a->getMTime() - $b->getMTime());
}; };
} elseif (self::SORT_BY_NONE === $sort) { } elseif (self::SORT_BY_NONE === $sort) {

View File

@ -356,7 +356,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
{ {
if (null === $this->projectDir) { if (null === $this->projectDir) {
$r = new \ReflectionObject($this); $r = new \ReflectionObject($this);
$dir = $rootDir = \dirname($r->getFileName());
if (!file_exists($dir = $r->getFileName())) {
throw new \LogicException(sprintf('Cannot auto-detect project dir for kernel of class "%s".', $r->name));
}
$dir = $rootDir = \dirname($dir);
while (!file_exists($dir.'/composer.json')) { while (!file_exists($dir.'/composer.json')) {
if ($dir === \dirname($dir)) { if ($dir === \dirname($dir)) {
return $this->projectDir = $rootDir; return $this->projectDir = $rootDir;

View File

@ -36,13 +36,8 @@ class KernelForTest extends Kernel
return $this->booted; return $this->booted;
} }
public function getCacheDir(): string public function getProjectDir(): string
{ {
return $this->getProjectDir().'/Tests/Fixtures/cache.'.$this->environment; return __DIR__;
}
public function getLogDir(): string
{
return $this->getProjectDir().'/Tests/Fixtures/logs';
} }
} }

View File

@ -129,7 +129,7 @@ class KernelTest extends TestCase
public function testBootSetsTheBootedFlagToTrue() public function testBootSetsTheBootedFlagToTrue()
{ {
// use test kernel to access isBooted() // use test kernel to access isBooted()
$kernel = $this->getKernelForTest(['initializeBundles', 'initializeContainer']); $kernel = $this->getKernel(['initializeBundles', 'initializeContainer']);
$kernel->boot(); $kernel->boot();
$this->assertTrue($kernel->isBooted()); $this->assertTrue($kernel->isBooted());
@ -608,7 +608,7 @@ EOF;
*/ */
public function testKernelStartTimeIsResetWhileBootingAlreadyBootedKernel() public function testKernelStartTimeIsResetWhileBootingAlreadyBootedKernel()
{ {
$kernel = $this->getKernelForTest(['initializeBundles'], true); $kernel = $this->getKernel(['initializeBundles'], [], true);
$kernel->boot(); $kernel->boot();
$preReBoot = $kernel->getStartTime(); $preReBoot = $kernel->getStartTime();
@ -656,36 +656,20 @@ EOF;
* @param array $methods Additional methods to mock (besides the abstract ones) * @param array $methods Additional methods to mock (besides the abstract ones)
* @param array $bundles Bundles to register * @param array $bundles Bundles to register
*/ */
protected function getKernel(array $methods = [], array $bundles = []): Kernel protected function getKernel(array $methods = [], array $bundles = [], bool $debug = false): Kernel
{ {
$methods[] = 'registerBundles'; $methods[] = 'registerBundles';
$kernel = $this $kernel = $this
->getMockBuilder('Symfony\Component\HttpKernel\Kernel') ->getMockBuilder(KernelForTest::class)
->setMethods($methods) ->setMethods($methods)
->setConstructorArgs(['test', false]) ->setConstructorArgs(['test', $debug])
->getMockForAbstractClass() ->getMock()
; ;
$kernel->expects($this->any()) $kernel->expects($this->any())
->method('registerBundles') ->method('registerBundles')
->willReturn($bundles) ->willReturn($bundles)
; ;
$p = new \ReflectionProperty($kernel, 'rootDir');
$p->setAccessible(true);
$p->setValue($kernel, __DIR__.'/Fixtures');
return $kernel;
}
protected function getKernelForTest(array $methods = [], $debug = false)
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
->setConstructorArgs(['test', $debug])
->setMethods($methods)
->getMock();
$p = new \ReflectionProperty($kernel, 'rootDir');
$p->setAccessible(true);
$p->setValue($kernel, __DIR__.'/Fixtures');
return $kernel; return $kernel;
} }
@ -703,6 +687,11 @@ class TestKernel implements HttpKernelInterface
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true): Response public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true): Response
{ {
} }
public function getProjectDir(): string
{
return __DIR__.'/Fixtures';
}
} }
class CustomProjectDirKernel extends Kernel class CustomProjectDirKernel extends Kernel

View File

@ -33,6 +33,10 @@ trait BlockingStoreTestTrait
* *
* This test is time sensible: the $clockDelay could be adjust. * This test is time sensible: the $clockDelay could be adjust.
* *
* It also fails when run with the global ./phpunit test suite.
*
* @group transient
*
* @requires extension pcntl * @requires extension pcntl
* @requires extension posix * @requires extension posix
* @requires function pcntl_sigwaitinfo * @requires function pcntl_sigwaitinfo

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Mailer\Transport;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger; use Psr\Log\NullLogger;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Mailer\DelayedSmtpEnvelope; use Symfony\Component\Mailer\DelayedSmtpEnvelope;
use Symfony\Component\Mailer\Event\MessageEvent; use Symfony\Component\Mailer\Event\MessageEvent;
use Symfony\Component\Mailer\Exception\TransportException; use Symfony\Component\Mailer\Exception\TransportException;
@ -35,7 +34,7 @@ abstract class AbstractTransport implements TransportInterface
public function __construct(EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) public function __construct(EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
{ {
$this->dispatcher = $dispatcher ?: new EventDispatcher(); $this->dispatcher = $dispatcher;
$this->logger = $logger ?: new NullLogger(); $this->logger = $logger ?: new NullLogger();
} }
@ -67,14 +66,17 @@ abstract class AbstractTransport implements TransportInterface
} }
} }
$event = new MessageEvent($message, $envelope, (string) $this); if (null !== $this->dispatcher) {
$this->dispatcher->dispatch($event); $event = new MessageEvent($message, $envelope, (string) $this);
$envelope = $event->getEnvelope(); $this->dispatcher->dispatch($event);
$envelope = $event->getEnvelope();
}
if (!$envelope->getRecipients()) { if (!$envelope->getRecipients()) {
return null; return null;
} }
$message = new SentMessage($event->getMessage(), $envelope); $message = new SentMessage($message, $envelope);
$this->doSend($message); $this->doSend($message);
$this->checkThrottling(); $this->checkThrottling();

View File

@ -20,6 +20,21 @@ use Symfony\Component\Messenger\Transport\RedisExt\Connection;
*/ */
class ConnectionTest extends TestCase class ConnectionTest extends TestCase
{ {
public static function setUpBeforeClass()
{
$redis = Connection::fromDsn('redis://localhost/queue');
try {
$redis->get();
} catch (TransportException $e) {
if (0 === strpos($e->getMessage(), 'ERR unknown command \'X')) {
self::markTestSkipped('Redis server >= 5 is required');
}
throw $e;
}
}
public function testFromInvalidDsn() public function testFromInvalidDsn()
{ {
$this->expectException(\InvalidArgumentException::class); $this->expectException(\InvalidArgumentException::class);

View File

@ -84,23 +84,6 @@ class ChainEncoderTest extends TestCase
$this->assertTrue($this->chainEncoder->needsNormalization(self::FORMAT_2)); $this->assertTrue($this->chainEncoder->needsNormalization(self::FORMAT_2));
} }
/**
* @dataProvider booleanProvider
*/
public function testNeedsNormalizationChainNormalizationAware($bool)
{
$chainEncoder = $this
->getMockBuilder('Symfony\Component\Serializer\Tests\Encoder\ChainNormalizationAwareEncoder')
->getMock();
$chainEncoder->method('supportsEncoding')->willReturn(true);
$chainEncoder->method('needsNormalization')->willReturn($bool);
$sut = new ChainEncoder([$chainEncoder]);
$this->assertEquals($bool, $sut->needsNormalization(self::FORMAT_1));
}
public function testNeedsNormalizationNormalizationAware() public function testNeedsNormalizationNormalizationAware()
{ {
$encoder = new NormalizationAwareEncoder(); $encoder = new NormalizationAwareEncoder();
@ -108,18 +91,6 @@ class ChainEncoderTest extends TestCase
$this->assertFalse($sut->needsNormalization(self::FORMAT_1)); $this->assertFalse($sut->needsNormalization(self::FORMAT_1));
} }
public function booleanProvider()
{
return [
[true],
[false],
];
}
}
class ChainNormalizationAwareEncoder extends ChainEncoder implements NormalizationAwareInterface
{
} }
class NormalizationAwareEncoder implements EncoderInterface, NormalizationAwareInterface class NormalizationAwareEncoder implements EncoderInterface, NormalizationAwareInterface