-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[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
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
{ | ||
$matched = false; | ||
$observed = []; | ||
$previousErrorHandler = null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 () { | ||
yceruto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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
150
src/Symfony/Bridge/PhpUnit/Tests/AssertDeprecationTraitTest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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?There was a problem hiding this comment.
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.