Skip to content

Commit 86f19c6

Browse files
committed
[PhpUnitBridge] Introduce AssertDeprecationTrait
1 parent a8c43b6 commit 86f19c6

18 files changed

+320
-116
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Symfony\Bridge\PhpUnit;
4+
5+
use PHPUnit\Framework\Assert;
6+
7+
trait AssertDeprecationTrait
8+
{
9+
/**
10+
* @param callable(): TReturn $callable
11+
* @return TReturn
12+
* @template TReturn
13+
*/
14+
private static function assertDeprecation(string $expectedMessage, callable $callable): mixed
15+
{
16+
$matched = false;
17+
$observed = [];
18+
$previousErrorHandler = null;
19+
$previousErrorHandler = set_error_handler(static function (int $type, string $message) use (&$previousErrorHandler, &$matched, &$observed, $expectedMessage) {
20+
if (($type === E_USER_DEPRECATED || $type === E_DEPRECATED)) {
21+
if (str_contains($message, $expectedMessage)) {
22+
return $matched = true;
23+
}
24+
25+
$observed[] = $message;
26+
}
27+
28+
return $previousErrorHandler(...func_get_args());
29+
}) ?? static function () {
30+
return false;
31+
};
32+
try {
33+
$result = $callable();
34+
} finally {
35+
restore_error_handler();
36+
}
37+
38+
if ([] === $observed) {
39+
Assert::assertTrue($matched, implode(PHP_EOL, [
40+
'The following deprecation has not been raised: ' . $expectedMessage,
41+
'No other deprecations have been observed.',
42+
]));
43+
} else {
44+
Assert::assertTrue($matched, implode(PHP_EOL, [
45+
'The following deprecation has not been raised: ' . $expectedMessage,
46+
'Instead, the following deprecations have been observed:',
47+
...array_map(static function (string $message) {
48+
return " - $message";
49+
}, $observed)
50+
]));
51+
}
52+
53+
return $result;
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?php
2+
3+
namespace Symfony\Bridge\PhpUnit\Tests;
4+
5+
use PHPUnit\Framework\ExpectationFailedException;
6+
use PHPUnit\Framework\TestCase;
7+
use Symfony\Bridge\PhpUnit\AssertDeprecationTrait;
8+
9+
final class AssertDeprecationTraitTest extends TestCase
10+
{
11+
public function testExpectedDeprecationHasBeenRaised()
12+
{
13+
$test = new class() {
14+
use AssertDeprecationTrait;
15+
16+
public function run(): string
17+
{
18+
return self::assertDeprecation(
19+
'Since foo/bar 47.11: Stop using this.',
20+
static function (): string {
21+
trigger_deprecation('foo/bar', '47.11', 'Stop using this.');
22+
23+
return 'foo';
24+
}
25+
);
26+
}
27+
};
28+
29+
self::assertSame('foo', $test->run());
30+
}
31+
32+
public function testExpectedDeprecationHasBeenRaisedAmongOthers()
33+
{
34+
$test = new class() {
35+
use AssertDeprecationTrait;
36+
37+
public function run(): string
38+
{
39+
return self::assertDeprecation(
40+
'Since foo/bar 47.11: Stop using this.',
41+
static function (): string {
42+
trigger_deprecation('fuz/baz', '0.8.15', 'Ignore me.');
43+
trigger_deprecation('foo/bar', '47.11', 'Stop using this.');
44+
45+
return 'foo';
46+
}
47+
);
48+
}
49+
};
50+
51+
$loggedDeprecations = [];
52+
$previous = null;
53+
$previous = set_error_handler(static function ($errno, $errstr) use (&$loggedDeprecations, &$previous) {
54+
if ($errno === E_USER_DEPRECATED) {
55+
$loggedDeprecations[] = $errstr;
56+
57+
return true;
58+
}
59+
60+
return $previous(...func_get_args());
61+
}) ?? static function () {
62+
return false;
63+
};
64+
65+
try {
66+
self::assertSame('foo', $test->run());
67+
} finally {
68+
restore_error_handler();
69+
}
70+
71+
self::assertSame(['Since fuz/baz 0.8.15: Ignore me.'], $loggedDeprecations);
72+
}
73+
74+
public function testNoDeprecationHasBeenRaised()
75+
{
76+
$test = new class() {
77+
use AssertDeprecationTrait;
78+
79+
public function run(): string
80+
{
81+
return self::assertDeprecation(
82+
'Since foo/bar 47.11: Stop using this.',
83+
static function (): void {
84+
}
85+
);
86+
}
87+
};
88+
89+
$e = null;
90+
try {
91+
$test->run();
92+
} catch (ExpectationFailedException $e) {
93+
}
94+
95+
self::assertNotNull($e);
96+
self::assertSame(
97+
"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.",
98+
$e->getMessage()
99+
);
100+
}
101+
102+
public function testOtherDeprecationsHaveBeenRaised()
103+
{
104+
$test = new class() {
105+
use AssertDeprecationTrait;
106+
107+
public function run(): string
108+
{
109+
return self::assertDeprecation(
110+
'Since foo/bar 47.11: Stop using this.',
111+
static function (): void {
112+
trigger_deprecation('fuz/baz', '0.8.15', 'Ignore me.');
113+
trigger_deprecation('fiz/buz', '0.8.16', 'And me as well.');
114+
}
115+
);
116+
}
117+
};
118+
119+
$e = null;
120+
$loggedDeprecations = [];
121+
$previous = null;
122+
$previous = set_error_handler(static function ($errno, $errstr) use (&$loggedDeprecations, &$previous) {
123+
if ($errno === E_USER_DEPRECATED) {
124+
$loggedDeprecations[] = $errstr;
125+
126+
return true;
127+
}
128+
129+
return $previous(...func_get_args());
130+
}) ?? static function () {
131+
return false;
132+
};
133+
try {
134+
$test->run();
135+
} catch (ExpectationFailedException $e) {
136+
} finally {
137+
restore_error_handler();
138+
}
139+
140+
self::assertNotNull($e);
141+
self::assertSame(
142+
"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.",
143+
$e->getMessage()
144+
);
145+
self::assertSame([
146+
'Since fuz/baz 0.8.15: Ignore me.',
147+
'Since fiz/buz 0.8.16: And me as well.',
148+
], $loggedDeprecations);
149+
}
150+
}

src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapConfigReaderTest.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace Symfony\Component\AssetMapper\Tests\ImportMap;
1313

1414
use PHPUnit\Framework\TestCase;
15-
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
15+
use Symfony\Bridge\PhpUnit\AssertDeprecationTrait;
1616
use Symfony\Component\AssetMapper\ImportMap\ImportMapConfigReader;
1717
use Symfony\Component\AssetMapper\ImportMap\ImportMapEntries;
1818
use Symfony\Component\AssetMapper\ImportMap\ImportMapEntry;
@@ -22,7 +22,7 @@
2222

2323
class ImportMapConfigReaderTest extends TestCase
2424
{
25-
use ExpectDeprecationTrait;
25+
use AssertDeprecationTrait;
2626

2727
private Filesystem $filesystem;
2828

@@ -171,7 +171,9 @@ public function testFindRootImportMapEntry()
171171
*/
172172
public function testDeprecatedMethodTriggerDeprecation()
173173
{
174-
$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.');
175-
ImportMapConfigReader::splitPackageNameAndFilePath('foo');
174+
self::assertDeprecation(
175+
'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.',
176+
static fn () => ImportMapConfigReader::splitPackageNameAndFilePath('foo'),
177+
);
176178
}
177179
}

src/Symfony/Component/AssetMapper/composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"symfony/framework-bundle": "^6.4|^7.0",
3232
"symfony/http-foundation": "^6.4|^7.0",
3333
"symfony/http-kernel": "^6.4|^7.0",
34+
"symfony/phpunit-bridge": "^7.1",
3435
"symfony/web-link": "^6.4|^7.0"
3536
},
3637
"conflict": {

src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace Symfony\Component\Cache\Tests\Adapter;
1313

1414
use Psr\Cache\CacheItemPoolInterface;
15-
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
15+
use Symfony\Bridge\PhpUnit\AssertDeprecationTrait;
1616
use Symfony\Component\Cache\Adapter\AbstractAdapter;
1717
use Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter;
1818

@@ -26,7 +26,7 @@
2626
*/
2727
class CouchbaseBucketAdapterTest extends AdapterTestCase
2828
{
29-
use ExpectDeprecationTrait;
29+
use AssertDeprecationTrait;
3030

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

3737
protected function setUp(): void
3838
{
39-
$this->expectDeprecation('Since symfony/cache 7.1: The "Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter" class is deprecated, use "Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter" instead.');
40-
4139
$this->client = AbstractAdapter::createConnection('couchbase://'.getenv('COUCHBASE_HOST').'/cache',
4240
['username' => getenv('COUCHBASE_USER'), 'password' => getenv('COUCHBASE_PASS')]
4341
);
42+
43+
if (!class_exists(CouchbaseBucketAdapter::class, false)) {
44+
self::assertDeprecation(
45+
'Since symfony/cache 7.1: The "Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter" class is deprecated, use "Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter" instead.',
46+
static fn () => class_exists(CouchbaseBucketAdapter::class),
47+
);
48+
}
4449
}
4550

4651
public function createCachePool($defaultLifetime = 0): CacheItemPoolInterface

src/Symfony/Component/Cache/Tests/Adapter/CouchbaseCollectionAdapterTest.php

+1-6
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,25 @@
1212
namespace Symfony\Component\Cache\Tests\Adapter;
1313

1414
use Psr\Cache\CacheItemPoolInterface;
15-
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1615
use Symfony\Component\Cache\Adapter\AbstractAdapter;
1716
use Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter;
1817

1918
/**
2019
* @requires extension couchbase <4.0.0
2120
* @requires extension couchbase >=3.0.5
2221
*
23-
* @group legacy integration
22+
* @group integration
2423
*
2524
* @author Antonio Jose Cerezo Aranda <aj.cerezo@gmail.com>
2625
*/
2726
class CouchbaseCollectionAdapterTest extends AdapterTestCase
2827
{
29-
use ExpectDeprecationTrait;
30-
3128
protected $skippedTests = [
3229
'testClearPrefix' => 'Couchbase cannot clear by prefix',
3330
];
3431

3532
public function createCachePool($defaultLifetime = 0): CacheItemPoolInterface
3633
{
37-
$this->expectDeprecation('Since symfony/cache 7.1: The "Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter" class is deprecated, use "Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter" instead.');
38-
3934
$client = AbstractAdapter::createConnection('couchbase://'.getenv('COUCHBASE_HOST').'/cache',
4035
['username' => getenv('COUCHBASE_USER'), 'password' => getenv('COUCHBASE_PASS')]
4136
);

src/Symfony/Component/Cache/composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"symfony/filesystem": "^6.4|^7.0",
4040
"symfony/http-kernel": "^6.4|^7.0",
4141
"symfony/messenger": "^6.4|^7.0",
42+
"symfony/phpunit-bridge": "^7.1",
4243
"symfony/var-dumper": "^6.4|^7.0"
4344
},
4445
"conflict": {

src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php

+10-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
1313

1414
use PHPUnit\Framework\TestCase;
15-
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
15+
use Symfony\Bridge\PhpUnit\AssertDeprecationTrait;
1616
use Symfony\Component\DependencyInjection\Alias;
1717
use Symfony\Component\DependencyInjection\Compiler\ResolveReferencesToAliasesPass;
1818
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -22,7 +22,7 @@
2222

2323
class ResolveReferencesToAliasesPassTest extends TestCase
2424
{
25-
use ExpectDeprecationTrait;
25+
use AssertDeprecationTrait;
2626

2727
public function testProcess()
2828
{
@@ -92,7 +92,6 @@ public function testResolveFactory()
9292
*/
9393
public function testDeprecationNoticeWhenReferencedByAlias()
9494
{
95-
$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.');
9695
$container = new ContainerBuilder();
9796

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

107-
$this->process($container);
106+
self::assertDeprecation(
107+
'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.',
108+
fn () => $this->process($container),
109+
);
108110
}
109111

110112
/**
@@ -114,7 +116,6 @@ public function testDeprecationNoticeWhenReferencedByAlias()
114116
*/
115117
public function testDeprecationNoticeWhenReferencedByDefinition()
116118
{
117-
$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.');
118119
$container = new ContainerBuilder();
119120

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

131-
$this->process($container);
132+
self::assertDeprecation(
133+
'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.',
134+
fn () => $this->process($container),
135+
);
132136
}
133137

134138
public function testNoDeprecationNoticeWhenReferencedByDeprecatedAlias()

0 commit comments

Comments
 (0)