Skip to content

Commit

Permalink
Merge branch '5.0' into 5.1
Browse files Browse the repository at this point in the history
* 5.0:
  Parse and render anonymous classes correctly on php 8
  Enable APCu for the php 8 build.
  [Process] Fix failing test on php 8.
  [HttpKernel] fix test
  Make PHP 8 green on Travis
  Revert "[Cache] allow DBAL v3"
  [PropertyAccessor] Added missing property path on php 8.
  Don't execute tests with DBAL 2.x on php 8.
  • Loading branch information
nicolas-grekas committed May 24, 2020
2 parents 4e6967e + 49eb5c9 commit 2ed4e0e
Show file tree
Hide file tree
Showing 27 changed files with 156 additions and 41 deletions.
19 changes: 19 additions & 0 deletions .travis.yml
Expand Up @@ -122,6 +122,23 @@ before_install:
}
export -f tpecl
install_apcu_dev () {
local ref=$1
local INI=$2
wget https://github.com/krakjoe/apcu/archive/${ref}.zip
unzip ${ref}.zip
cd apcu-${ref}
phpize
./configure
make
mv modules/apcu.so $(php -r "echo ini_get('extension_dir');")
echo 'extension = apcu.so' >> $INI
cd ..
rm -rf apcu-${ref} ${ref}.zip
}
export -f install_apcu_dev
- |
# Install sigchild-enabled PHP to test the Process component on the lowest PHP matrix line
if [[ ! $deps && $TRAVIS_PHP_VERSION = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then
Expand Down Expand Up @@ -155,6 +172,7 @@ before_install:
fi
if [[ $PHP = nightly ]]; then
tfold ext.memcached tpecl memcached-3.1.5 memcached.so $INI
tfold ext.apcu install_apcu_dev 9c36db45100d4d27ec33072f4be90f1f5a0108b7 $INI
else
tfold ext.apcu tpecl apcu-5.1.18 apcu.so $INI
tfold ext.mongodb tpecl mongodb-1.6.16 mongodb.so $INI
Expand Down Expand Up @@ -236,6 +254,7 @@ install:
# Set composer's platform to php 7.4 if we're on php 8.
if [[ $PHP = nightly ]]; then
composer config platform.php 7.4.99
export SYMFONY_DEPRECATIONS_HELPER=weak
fi
- |
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Cache/Tests/Adapter/PdoAdapterTest.php
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\Cache\Tests\Adapter;

use Doctrine\DBAL\Version;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
Expand All @@ -30,6 +31,10 @@ public static function setUpBeforeClass(): void
self::markTestSkipped('Extension pdo_sqlite required.');
}

if (\PHP_VERSION_ID >= 80000 && class_exists(Version::class)) {
self::markTestSkipped('Doctrine DBAL 2.x is incompatible with PHP 8.');
}

self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');

$pool = new PdoAdapter('sqlite:'.self::$dbFile);
Expand Down
Expand Up @@ -15,6 +15,7 @@
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Version;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
Expand All @@ -34,6 +35,10 @@ public static function setUpBeforeClass(): void
self::markTestSkipped('Extension pdo_sqlite required.');
}

if (\PHP_VERSION_ID >= 80000 && class_exists(Version::class)) {
self::markTestSkipped('Doctrine DBAL 2.x is incompatible with PHP 8.');
}

self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
}

Expand Down
12 changes: 8 additions & 4 deletions src/Symfony/Component/Console/Tests/ApplicationTest.php
Expand Up @@ -883,7 +883,8 @@ public function testRenderAnonymousException()
$application = new Application();
$application->setAutoExit(false);
$application->register('foo')->setCode(function () {
throw new class('') extends \InvalidArgumentException { };
throw new class('') extends \InvalidArgumentException {
};
});
$tester = new ApplicationTester($application);

Expand All @@ -893,7 +894,8 @@ public function testRenderAnonymousException()
$application = new Application();
$application->setAutoExit(false);
$application->register('foo')->setCode(function () {
throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', get_debug_type(new class() { })));
throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() {
})));
});
$tester = new ApplicationTester($application);

Expand All @@ -906,7 +908,8 @@ public function testRenderExceptionStackTraceContainsRootException()
$application = new Application();
$application->setAutoExit(false);
$application->register('foo')->setCode(function () {
throw new class('') extends \InvalidArgumentException { };
throw new class('') extends \InvalidArgumentException {
};
});
$tester = new ApplicationTester($application);

Expand All @@ -916,7 +919,8 @@ public function testRenderExceptionStackTraceContainsRootException()
$application = new Application();
$application->setAutoExit(false);
$application->register('foo')->setCode(function () {
throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', get_debug_type(new class() { })));
throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() {
})));
});
$tester = new ApplicationTester($application);

Expand Down
Expand Up @@ -26,6 +26,7 @@
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\FooVariadic;
use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\MultipleArgumentsOptionalScalarNotReallyOptional;
use Symfony\Component\DependencyInjection\TypedReference;

require_once __DIR__.'/../Fixtures/includes/autowiring_classes.php';
Expand Down Expand Up @@ -452,6 +453,9 @@ public function testNoTypeArgsCannotBeAutowired()
}
}

/**
* @requires PHP < 8
*/
public function testOptionalScalarNotReallyOptionalUsesDefaultValue()
{
$container = new ContainerBuilder();
Expand Down
@@ -0,0 +1,14 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures\includes;

use Symfony\Component\DependencyInjection\Tests\Compiler\A;
use Symfony\Component\DependencyInjection\Tests\Compiler\Lille;

class MultipleArgumentsOptionalScalarNotReallyOptional
{
public function __construct(A $a, $foo = 'default_val', Lille $lille)
{
}
}

Expand Up @@ -186,12 +186,6 @@ public function __construct(A $a, Lille $lille, $foo = 'some_val')
{
}
}
class MultipleArgumentsOptionalScalarNotReallyOptional
{
public function __construct(A $a, $foo = 'default_val', Lille $lille)
{
}
}

/*
* Classes used for testing createResourceForClass
Expand Down
Expand Up @@ -75,7 +75,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod
$e->setStatusCode($statusCode);
$e->setHeaders($headers);
$e->setTraceFromThrowable($exception);
$e->setClass(\get_class($exception));
$e->setClass(get_debug_type($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());

Expand Down
24 changes: 24 additions & 0 deletions src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php
Expand Up @@ -365,6 +365,26 @@ public function testHandleUserError()
}
}

public function testHandleErrorWithAnonymousClass()
{
$handler = ErrorHandler::register();
$handler->throwAt(3, true);
try {
$handler->handleError(3, 'foo '.\get_class(new class() extends \stdClass {
}).' bar', 'foo.php', 12);
$this->fail('Exception expected.');
} catch (\ErrorException $e) {
} finally {
restore_error_handler();
restore_exception_handler();
}

$this->assertSame('foo stdClass@anonymous bar', $e->getMessage());
$this->assertSame(3, $e->getSeverity());
$this->assertSame('foo.php', $e->getFile());
$this->assertSame(12, $e->getLine());
}

public function testHandleDeprecation()
{
$logArgCheck = function ($level, $message, $context) {
Expand Down Expand Up @@ -433,6 +453,10 @@ public function handleExceptionProvider(): array
{
return [
['Uncaught Exception: foo', new \Exception('foo')],
['Uncaught Exception: foo', new class('foo') extends \RuntimeException {
}],
['Uncaught Exception: foo stdClass@anonymous bar', new \RuntimeException('foo '.\get_class(new class() extends \stdClass {
}).' bar')],
['Uncaught Error: bar', new \Error('bar')],
['Uncaught ccc', new \ErrorException('ccc')],
];
Expand Down
Expand Up @@ -359,6 +359,11 @@ public function testAnonymousClass()

$this->assertSame('RuntimeException@anonymous', $flattened->getClass());

$flattened->setClass(\get_class(new class('Oops') extends NotFoundHttpException {
}));

$this->assertSame('Symfony\Component\HttpKernel\Exception\NotFoundHttpException@anonymous', $flattened->getClass());

$flattened = FlattenException::createFromThrowable(new \Exception(sprintf('Class "%s" blah.', \get_class(new class() extends \RuntimeException {
}))));

Expand Down
5 changes: 2 additions & 3 deletions src/Symfony/Component/HttpKernel/Kernel.php
Expand Up @@ -223,9 +223,7 @@ public function getBundles()
public function getBundle(string $name)
{
if (!isset($this->bundles[$name])) {
$class = get_debug_type($this);

throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, $class));
throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, get_debug_type($this)));
}

return $this->bundles[$name];
Expand Down Expand Up @@ -400,6 +398,7 @@ protected function getContainerClass()
$class = static::class;
$class = false !== strpos($class, "@anonymous\0") ? get_parent_class($class).str_replace('.', '_', ContainerBuilder::hash($class)) : $class;
$class = str_replace('\\', '_', $class).ucfirst($this->environment).($this->debug ? 'Debug' : '').'Container';

if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $class)) {
throw new \InvalidArgumentException(sprintf('The environment "%s" contains invalid characters, it can only contain characters allowed in PHP class names.', $this->environment));
}
Expand Down
Expand Up @@ -204,19 +204,19 @@ public function testGetNullableArguments()
$request = Request::create('/');
$request->attributes->set('foo', 'foo');
$request->attributes->set('bar', new \stdClass());
$request->attributes->set('mandatory', 'mandatory');
$request->attributes->set('last', 'last');
$controller = [new NullableController(), 'action'];

$this->assertEquals(['foo', new \stdClass(), 'value', 'mandatory'], self::$resolver->getArguments($request, $controller));
$this->assertEquals(['foo', new \stdClass(), 'value', 'last'], self::$resolver->getArguments($request, $controller));
}

public function testGetNullableArgumentsWithDefaults()
{
$request = Request::create('/');
$request->attributes->set('mandatory', 'mandatory');
$request->attributes->set('last', 'last');
$controller = [new NullableController(), 'action'];

$this->assertEquals([null, null, 'value', 'mandatory'], self::$resolver->getArguments($request, $controller));
$this->assertEquals([null, null, 'value', 'last'], self::$resolver->getArguments($request, $controller));
}

public function testGetSessionArguments()
Expand Down
Expand Up @@ -80,7 +80,7 @@ public function testSignature5()

$this->assertEquals([
new ArgumentMetadata('foo', 'array', false, true, null, true),
new ArgumentMetadata('bar', null, false, false, null),
new ArgumentMetadata('bar', null, false, true, null, true),
], $arguments);
}

Expand Down Expand Up @@ -113,7 +113,7 @@ public function testNullableTypesSignature()
new ArgumentMetadata('foo', 'string', false, false, null, true),
new ArgumentMetadata('bar', \stdClass::class, false, false, null, true),
new ArgumentMetadata('baz', 'string', false, true, 'value', true),
new ArgumentMetadata('mandatory', null, false, false, null, true),
new ArgumentMetadata('last', 'string', false, true, '', false),
], $arguments);
}

Expand All @@ -133,7 +133,7 @@ private function signature4($foo = 'default', $bar = 500, $baz = [])
{
}

private function signature5(array $foo = null, $bar)
private function signature5(array $foo = null, $bar = null)
{
}
}
Expand Up @@ -13,7 +13,7 @@

class NullableController
{
public function action(?string $foo, ?\stdClass $bar, ?string $baz = 'value', $mandatory)
public function action(?string $foo, ?\stdClass $bar, ?string $baz = 'value', string $last = '')
{
}
}
21 changes: 21 additions & 0 deletions src/Symfony/Component/HttpKernel/Tests/KernelTest.php
Expand Up @@ -536,6 +536,27 @@ public function testKernelStartTimeIsResetWhileBootingAlreadyBootedKernel()
$this->assertGreaterThan($preReBoot, $kernel->getStartTime());
}

public function testAnonymousKernelGeneratesValidContainerClass(): void
{
$kernel = new class('test', true) extends Kernel {
public function registerBundles(): iterable
{
return [];
}

public function registerContainerConfiguration(LoaderInterface $loader): void
{
}

public function getContainerClass(): string
{
return parent::getContainerClass();
}
};

$this->assertRegExp('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*TestDebugContainer$/', $kernel->getContainerClass());
}

/**
* Returns a mock for the BundleInterface.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Lock/Tests/Store/PdoDbalStoreTest.php
Expand Up @@ -14,6 +14,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Version;
use Symfony\Component\Lock\PersistingStoreInterface;
use Symfony\Component\Lock\Store\PdoStore;

Expand All @@ -32,6 +33,10 @@ public static function setUpBeforeClass(): void
{
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_lock');

if (\PHP_VERSION_ID >= 80000 && class_exists(Version::class)) {
self::markTestSkipped('Doctrine DBAL 2.x is incompatible with PHP 8.');
}

$store = new PdoStore(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]));
$store->createTable();
}
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\Lock\Tests\Store;

use Doctrine\DBAL\Version;
use Symfony\Component\Lock\Key;
use Symfony\Component\Lock\PersistingStoreInterface;
use Symfony\Component\Lock\Store\PdoStore;
Expand All @@ -30,6 +31,10 @@ public static function setUpBeforeClass(): void
{
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_lock');

if (\PHP_VERSION_ID >= 80000 && class_exists(Version::class)) {
self::markTestSkipped('Doctrine DBAL 2.x is incompatible with PHP 8.');
}

$store = new PdoStore('sqlite:'.self::$dbFile);
$store->createTable();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Lock/composer.json
Expand Up @@ -21,7 +21,7 @@
"symfony/polyfill-php80": "^1.15"
},
"require-dev": {
"doctrine/dbal": "~2.5",
"doctrine/dbal": "^2.5|^3.0",
"mongodb/mongodb": "~1.1",
"predis/predis": "~1.0"
},
Expand Down
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Messenger\Bridge\Doctrine\Tests\Transport;

use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Version;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Messenger\Bridge\Doctrine\Tests\Fixtures\DummyMessage;
use Symfony\Component\Messenger\Bridge\Doctrine\Transport\Connection;
Expand All @@ -28,6 +29,13 @@ class DoctrineIntegrationTest extends TestCase
/** @var string */
private $sqliteFile;

public static function setUpBeforeClass(): void
{
if (\PHP_VERSION_ID >= 80000 && class_exists(Version::class)) {
self::markTestSkipped('Doctrine DBAL 2.x is incompatible with PHP 8.');
}
}

protected function setUp(): void
{
$this->sqliteFile = sys_get_temp_dir().'/symfony.messenger.sqlite';
Expand Down

0 comments on commit 2ed4e0e

Please sign in to comment.