8000 [PhpUnitBridge] Introduce AssertDeprecationTrait by derrabus · Pull Request #54538 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[PhpUnitBridge] Introduce AssertDeprecationTrait #54538

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/Symfony/Bridge/PhpUnit/AssertDeprecationTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?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\Bridge\PhpUnit;

use PHPUnit\Framework\Assert;

trait AssertDeprecationTrait
{
/**
* @param callable(): TReturn $callable
* @return TReturn
* @template TReturn
*/
private static function assertDeprecation(string $expectedMessage, callable $callable): mixed
Copy link
Member
@yceruto yceruto Apr 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if dealing with \Closure instead would be enough and faster?

Copy link
< 10000 div class="d-none d-sm-flex"> Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think narrowing to Closure will give uns any benefit in this particular case.

{
$matched = false;
$observed = [];
$previousErrorHandler = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this initialization necessary? AFAICS it should work without it.

$previousErrorHandler = set_error_handler(static function (int $type, string $message) use (&$previousErrorHandler, &$matched, &$observed, $expectedMessage) {
if (($type === E_USER_DEPRECATED || $type === E_DEPRECATED)) {
if (str_contains($message, $expectedMessage)) {
return $matched = true;
}

$observed[] = $message;
}

return $previousErrorHandler(...func_get_args());
}) ?? static function () {
return false;
};
try {
$result = $callable();
} finally {
restore_error_handler();
}

if ([] === $observed) {
Assert::assertTrue($matched, implode(PHP_EOL, [
'The following deprecation has not been raised: ' . $expectedMessage,
'No other deprecations have been observed.',
]));
} else {
Assert::assertTrue($matched, implode(PHP_EOL, array_merge(
[
'The following deprecation has not been raised: ' . $expectedMessage,
'Instead, the following deprecations have been observed:',
],
array_map(static function (string $message) {
return " - $message";
}, $observed),
)));
}

return $result;
}
}
150 changes: 150 additions & 0 deletions src/Symfony/Bridge/PhpUnit/Tests/AssertDeprecationTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<?php

namespace Symfony\Bridge\PhpUnit\Tests;

use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\AssertDeprecationTrait;

final class AssertDeprecationTraitTest extends TestCase
{
public function testExpectedDeprecationHasBeenRaised()
{
$test = new class() {
use AssertDeprecationTrait;

public function run(): string
{
return self::assertDeprecation(
'Since foo/bar 47.11: Stop using this.',
static function (): string {
trigger_deprecation('foo/bar', '47.11', 'Stop using this.');

return 'foo';
}
);
}
};

self::assertSame('foo', $test->run());
}

public function testExpectedDeprecationHasBeenRaisedAmongOthers()
{
$test = new class() {
use AssertDeprecationTrait;

public function run(): string
{
return self::assertDeprecation(
'Since foo/bar 47.11: Stop using this.',
static function (): string {
trigger_deprecation('fuz/baz', '0.8.15', 'Ignore me.');
trigger_deprecation('foo/bar', '47.11', 'Stop using this.');

return 'foo';
}
);
}
};

$loggedDeprecations = [];
$previous = null;
$previous = set_error_handler(static function ($errno, $errstr) use (&$loggedDeprecations, &$previous) {
if ($errno === E_USER_DEPRECATED) {
$loggedDeprecations[] = $errstr;

return true;
}

return $previous(...func_get_args());
}) ?? static function () {
return false;
};

try {
self::assertSame('foo', $test->run());
} finally {
restore_error_handler();
}

self::assertSame(['Since fuz/baz 0.8.15: Ignore me.'], $loggedDeprecations);
}

public function testNoDeprecationHasBeenRaised()
{
$test = new class() {
use AssertDeprecationTrait;

public function run(): string
{
return self::assertDeprecation(
'Since foo/bar 47.11: Stop using this.',
static function (): void {
}
);
}
};

$e = null;
try {
$test->run();
} catch (ExpectationFailedException $e) {
}

self::assertNotNull($e);
self::assertSame(
"The following deprecation has not been raised: Since foo/bar 47.11: Stop using this.\nNo other deprecations have been observed.\nFailed asserting that false is true.",
$e->getMessage()
);
}

public function testOtherDeprecationsHaveBeenRaised()
{
$test = new class() {
use AssertDeprecationTrait;

public function run(): string
{
return self::assertDeprecation(
'Since foo/bar 47.11: Stop using this.',
static function (): void {
trigger_deprecation('fuz/baz', '0.8.15', 'Ignore me.');
trigger_deprecation('fiz/buz', '0.8.16', 'And me as well.');
}
);
}
};

$e = null;
$loggedDeprecations = [];
$previous = null;
$previous = set_error_handler(static function ($errno, $errstr) use (&$loggedDeprecations, &$previous) {
if ($errno === E_USER_DEPRECATED) {
$loggedDeprecations[] = $errstr;

return true;
}

return $previous(...func_get_args());
}) ?? static function () {
return false;
};
try {
$test->run();
} catch (ExpectationFailedException $e) {
} finally {
restore_error_handler();
}

self::assertNotNull($e);
self::assertSame(
"The following deprecation has not been raised: Since foo/bar 47.11: Stop using this.\nInstead, the following deprecations have been observed:\n - Since fuz/baz 0.8.15: Ignore me.\n - Since fiz/buz 0.8.16: And me as well.\nFailed asserting that false is true.",
$e->getMessage()
);
self::assertSame([
'Since fuz/baz 0.8.15: Ignore me.',
'Since fiz/buz 0.8.16: And me as well.',
], $loggedDeprecations);
}
}
F438
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Symfony\Component\AssetMapper\Tests\ImportMap;

use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Bridge\PhpUnit\AssertDeprecationTrait;
use Symfony\Component\AssetMapper\ImportMap\ImportMapConfigReader;
use Symfony\Component\AssetMapper\ImportMap\ImportMapEntries;
use Symfony\Component\AssetMapper\ImportMap\ImportMapEntry;
Expand All @@ -22,7 +22,7 @@

class ImportMapConfigReaderTest extends TestCase
{
use ExpectDeprecationTrait;
use AssertDeprecationTrait;

private Filesystem $filesystem;

Expand Down Expand Up @@ -171,7 +171,9 @@ public function testFindRootImportMapEntry()
*/
public function testDeprecatedMethodTriggerDeprecation()
{
$this->expectDeprecation('Since symfony/asset-mapper 7.1: The method "Symfony\Component\AssetMapper\ImportMap\ImportMapConfigReader::splitPackageNameAndFilePath()" is deprecated and will be removed in 8.0. Use ImportMapEntry::splitPackageNameAndFilePath() instead.');
ImportMapConfigReader::splitPackageNameAndFilePath('foo');
self::assertDeprecation(
'Since symfony/asset-mapper 7.1: The method "Symfony\Component\AssetMapper\ImportMap\ImportMapConfigReader::splitPackageNameAndFilePath()" is deprecated and will be removed in 8.0. Use ImportMapEntry::splitPackageNameAndFilePath() instead.',
static fn () => ImportMapConfigReader::splitPackageNameAndFilePath('foo'),
);
}
}
1 change: 1 addition & 0 deletions src/Symfony/Component/AssetMapper/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"symfony/framework-bundle": "^6.4|^7.0",
"symfony/http-foundation": "^6.4|^7.0",
"symfony/http-kernel": "^6.4|^7.0",
"symfony/phpunit-bridge": "^7.1",
"symfony/web-link": "^6.4|^7.0"
},
"conflict": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Symfony\Component\Cache\Tests\Adapter;

use Psr\Cache\CacheItemPoolInterface;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Bridge\PhpUnit\AssertDeprecationTrait;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter;

Expand All @@ -26,7 +26,7 @@
*/
class CouchbaseBucketAdapterTest extends AdapterTestCase
{
use ExpectDeprecationTrait;
use AssertDeprecationTrait;

protected $skippedTests = [
'testClearPrefix' => 'Couchbase cannot clear by prefix',
Expand All @@ -36,11 +36,16 @@ class CouchbaseBucketAdapterTest extends AdapterTestCase

protected function setUp(): void
{
$this->expectDeprecation('Since symfony/cache 7.1: The "Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter" class is deprecated, use "Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter" instead.');

$this->client = AbstractAdapter::createConnection('couchbase://'.getenv('COUCHBASE_HOST').'/cache',
['username' => getenv('COUCHBASE_USER'), 'password' => getenv('COUCHBASE_PASS')]
);

if (!class_exists(CouchbaseBucketAdapter::class, false)) {
self::assertDeprecation(
'Since symfony/cache 7.1: The "Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter" class is deprecated, use "Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter" instead.',
static fn () => class_exists(CouchbaseBucketAdapter::class),
);
}
}

public function createCachePool($defaultLifetime = 0): CacheItemPoolInterface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,25 @@
namespace Symfony\Component\Cache\Tests\Adapter;

use Psr\Cache\CacheItemPoolInterface;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter;

/**
* @requires extension couchbase <4.0.0
* @requires extension couchbase >=3.0.5
*
* @group legacy integration
* @group integration
*
* @author Antonio Jose Cerezo Aranda <aj.cerezo@gmail.com>
*/
class CouchbaseCollectionAdapterTest extends AdapterTestCase
{
use ExpectDeprecationTrait;

protected $skippedTests = [
'testClearPrefix' => 'Couchbase cannot clear by prefix',
];

public function createCachePool($defaultLifetime = 0): CacheItemPoolInterface
{
$this->expectDeprecation('Since symfony/cache 7.1: The "Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter" class is deprecated, use "Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter" instead.');

$client = AbstractAdapter::createConnection('couchbase://'.getenv('COUCHBASE_HOST').'/cache',
['username' => getenv('COUCHBASE_USER'), 'password' => getenv('COUCHBASE_PASS')]
);
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Cache/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"symfony/filesystem": "^6.4|^7.0",
"symfony/http-kernel": "^6.4|^7.0",
"symfony/messenger": "^6.4|^7.0",
"symfony/phpunit-bridge": "^7.1",
"symfony/var-dumper": "^6.4|^7.0"
},
"conflict": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Bridge\PhpUnit\AssertDeprecationTrait;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Compiler\ResolveReferencesToAliasesPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -22,7 +22,7 @@

class ResolveReferencesToAliasesPassTest extends TestCase
{
use ExpectDeprecationTrait;
use AssertDeprecationTrait;

public function testProcess()
{
Expand Down Expand Up @@ -92,7 +92,6 @@ public function testResolveFactory()
*/
public function testDeprecationNoticeWhenReferencedByAlias()
{
$this->expectDeprecation('Since foobar 1.2.3.4: The "deprecated_foo_alias" service alias is deprecated. You should stop using it, as it will be removed in the future. It is being referenced by the "alias" alias.');
$container = new ContainerBuilder();

$container->register('foo', 'stdClass');
Expand All @@ -104,7 +103,10 @@ public function testDeprecationNoticeWhenReferencedByAlias()
$alias = new Alias('deprecated_foo_alias');
$container->setAlias('alias', $alias);

$this->process($container);
self::assertDeprecation(
'Since foobar 1.2.3.4: The "deprecated_foo_alias" service alias is deprecated. You should stop using it, as it will be removed in the future. It is being referenced by the "alias" alias.',
fn () => $this->process($container),
);
}

/**
Expand All @@ -114,7 +116,6 @@ public function testDeprecationNoticeWhenReferencedByAlias()
*/
public function testDeprecationNoticeWhenReferencedByDefinition()
{
$this->expectDeprecation('Since foobar 1.2.3.4: The "foo_aliased" service alias is deprecated. You should stop using it, as it will be removed in the future. It is being referenced by the "definition" service.');
$container = new ContainerBuilder();

$container->register('foo', 'stdClass');
Expand All @@ -128,7 +129,10 @@ public function testDeprecationNoticeWhenReferencedByDefinition()
->setArguments([new Reference('foo_aliased')])
;

$this->process($container);
self::assertDeprecation(
'Since foobar 1.2.3.4: The "foo_aliased" service alias is deprecated. You should stop using it, as it will be removed in the future. It is being referenced by the "definition" service.',
fn () => $this->process($container),
);
}

public function testNoDeprecationNoticeWhenReferencedByDeprecatedAlias()
Expand Down
Loading
Loading
0