diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 6972de48cc..5eb9179d7f 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -319,7 +319,7 @@ class DeprecationErrorHandler private static function getPhpUnitErrorHandler() { 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) { return 'PHPUnit\Util\ErrorHandler::handleError'; diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php index 7753f1b25f..cf3e946f6a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php @@ -131,9 +131,9 @@ EOT private static function getDotenvVars(): array { $vars = []; - foreach (explode(',', getenv('SYMFONY_DOTENV_VARS')) as $name) { - if ('' !== $name && false !== $value = getenv($name)) { - $vars[$name] = $value; + foreach (explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? $_ENV['SYMFONY_DOTENV_VARS'] ?? '') as $name) { + if ('' !== $name && isset($_ENV[$name])) { + $vars[$name] = $_ENV[$name]; } } diff --git a/src/Symfony/Component/BrowserKit/HttpBrowser.php b/src/Symfony/Component/BrowserKit/HttpBrowser.php index d36cf23712..b2331ea492 100644 --- a/src/Symfony/Component/BrowserKit/HttpBrowser.php +++ b/src/Symfony/Component/BrowserKit/HttpBrowser.php @@ -23,8 +23,6 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; * to make real HTTP requests. * * @author Fabien Potencier - * - * @final */ class HttpBrowser extends AbstractBrowser { @@ -32,7 +30,7 @@ class HttpBrowser extends AbstractBrowser 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__)); } diff --git a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php index 6539bfff66..8b437630d0 100644 --- a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php @@ -113,7 +113,7 @@ class ChoiceFormField extends FormField /** * 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 */ diff --git a/src/Symfony/Component/DomCrawler/Field/FileFormField.php b/src/Symfony/Component/DomCrawler/Field/FileFormField.php index 9e21c9c4b9..9abdca8827 100644 --- a/src/Symfony/Component/DomCrawler/Field/FileFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/FileFormField.php @@ -48,7 +48,7 @@ class FileFormField extends FormField /** * 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) { diff --git a/src/Symfony/Component/DomCrawler/Field/FormField.php b/src/Symfony/Component/DomCrawler/Field/FormField.php index 51d875514c..0bc4f54479 100644 --- a/src/Symfony/Component/DomCrawler/Field/FormField.php +++ b/src/Symfony/Component/DomCrawler/Field/FormField.php @@ -99,7 +99,7 @@ abstract class FormField /** * 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) { diff --git a/src/Symfony/Component/Finder/Iterator/SortableIterator.php b/src/Symfony/Component/Finder/Iterator/SortableIterator.php index cc955a7108..479489367a 100644 --- a/src/Symfony/Component/Finder/Iterator/SortableIterator.php +++ b/src/Symfony/Component/Finder/Iterator/SortableIterator.php @@ -41,15 +41,15 @@ class SortableIterator implements \IteratorAggregate $order = $reverseOrder ? -1 : 1; 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()); }; } 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()); }; } 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()) { return -$order; } elseif ($a->isFile() && $b->isDir()) { @@ -59,15 +59,15 @@ class SortableIterator implements \IteratorAggregate return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); }; } 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()); }; } 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()); }; } 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()); }; } elseif (self::SORT_BY_NONE === $sort) { diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index d2ef8515b4..c4096308ca 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -356,7 +356,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl { if (null === $this->projectDir) { $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')) { if ($dir === \dirname($dir)) { return $this->projectDir = $rootDir; diff --git a/src/Symfony/Component/HttpKernel/Tests/Fixtures/KernelForTest.php b/src/Symfony/Component/HttpKernel/Tests/Fixtures/KernelForTest.php index 5ba41ce038..f3b1951b83 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fixtures/KernelForTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fixtures/KernelForTest.php @@ -36,13 +36,8 @@ class KernelForTest extends Kernel return $this->booted; } - public function getCacheDir(): string + public function getProjectDir(): string { - return $this->getProjectDir().'/Tests/Fixtures/cache.'.$this->environment; - } - - public function getLogDir(): string - { - return $this->getProjectDir().'/Tests/Fixtures/logs'; + return __DIR__; } } diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index 238b46a8dc..065a3ea148 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -129,7 +129,7 @@ class KernelTest extends TestCase public function testBootSetsTheBootedFlagToTrue() { // use test kernel to access isBooted() - $kernel = $this->getKernelForTest(['initializeBundles', 'initializeContainer']); + $kernel = $this->getKernel(['initializeBundles', 'initializeContainer']); $kernel->boot(); $this->assertTrue($kernel->isBooted()); @@ -608,7 +608,7 @@ EOF; */ public function testKernelStartTimeIsResetWhileBootingAlreadyBootedKernel() { - $kernel = $this->getKernelForTest(['initializeBundles'], true); + $kernel = $this->getKernel(['initializeBundles'], [], true); $kernel->boot(); $preReBoot = $kernel->getStartTime(); @@ -656,36 +656,20 @@ EOF; * @param array $methods Additional methods to mock (besides the abstract ones) * @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'; $kernel = $this - ->getMockBuilder('Symfony\Component\HttpKernel\Kernel') + ->getMockBuilder(KernelForTest::class) ->setMethods($methods) - ->setConstructorArgs(['test', false]) - ->getMockForAbstractClass() + ->setConstructorArgs(['test', $debug]) + ->getMock() ; $kernel->expects($this->any()) ->method('registerBundles') ->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; } @@ -703,6 +687,11 @@ class TestKernel implements HttpKernelInterface public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true): Response { } + + public function getProjectDir(): string + { + return __DIR__.'/Fixtures'; + } } class CustomProjectDirKernel extends Kernel diff --git a/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php b/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php index 9c9ecdcd2f..55d8d34c86 100644 --- a/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php +++ b/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php @@ -33,6 +33,10 @@ trait BlockingStoreTestTrait * * 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 posix * @requires function pcntl_sigwaitinfo diff --git a/src/Symfony/Component/Mailer/Transport/AbstractTransport.php b/src/Symfony/Component/Mailer/Transport/AbstractTransport.php index 71d7636d06..fb817f75b5 100644 --- a/src/Symfony/Component/Mailer/Transport/AbstractTransport.php +++ b/src/Symfony/Component/Mailer/Transport/AbstractTransport.php @@ -13,7 +13,6 @@ namespace Symfony\Component\Mailer\Transport; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; -use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Mailer\DelayedSmtpEnvelope; use Symfony\Component\Mailer\Event\MessageEvent; use Symfony\Component\Mailer\Exception\TransportException; @@ -35,7 +34,7 @@ abstract class AbstractTransport implements TransportInterface public function __construct(EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) { - $this->dispatcher = $dispatcher ?: new EventDispatcher(); + $this->dispatcher = $dispatcher; $this->logger = $logger ?: new NullLogger(); } @@ -67,14 +66,17 @@ abstract class AbstractTransport implements TransportInterface } } - $event = new MessageEvent($message, $envelope, (string) $this); - $this->dispatcher->dispatch($event); - $envelope = $event->getEnvelope(); + if (null !== $this->dispatcher) { + $event = new MessageEvent($message, $envelope, (string) $this); + $this->dispatcher->dispatch($event); + $envelope = $event->getEnvelope(); + } + if (!$envelope->getRecipients()) { return null; } - $message = new SentMessage($event->getMessage(), $envelope); + $message = new SentMessage($message, $envelope); $this->doSend($message); $this->checkThrottling(); diff --git a/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php index 2869ccbe8b..08f93b0393 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php @@ -20,6 +20,21 @@ use Symfony\Component\Messenger\Transport\RedisExt\Connection; */ 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() { $this->expectException(\InvalidArgumentException::class); diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php index 4b97fdf534..82aa2934d9 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php @@ -84,23 +84,6 @@ class ChainEncoderTest extends TestCase $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() { $encoder = new NormalizationAwareEncoder(); @@ -108,18 +91,6 @@ class ChainEncoderTest extends TestCase $this->assertFalse($sut->needsNormalization(self::FORMAT_1)); } - - public function booleanProvider() - { - return [ - [true], - [false], - ]; - } -} - -class ChainNormalizationAwareEncoder extends ChainEncoder implements NormalizationAwareInterface -{ } class NormalizationAwareEncoder implements EncoderInterface, NormalizationAwareInterface