Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fixed PHPUnit 8.3 incompatibility: method handleError was renamed to __invoke#32890

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed

Conversation

@karser
Copy link
Contributor

@karserkarser commentedAug 2, 2019
edited
Loading

QA
Branch?4.3
Bug fix?yes
New feature?no
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets#32879
LicenseMIT

The PHPUnit methodhandleError was renamed to__invoke in v8.3.

So we should check in SymfonyDeprecationErrorHandler if methodhandleError exists, otherwise call__invoke

It works with phpunit v8.2.5 and 8.3.2.
The PHPUnit handler is called when I trigger some error, e.giconv('fdsfs', 'fsdfds', '');

dominikhajduk, trboltom, and pierre-H reacted with thumbs up emoji
@smoench
Copy link
Contributor

@karser OnDeprecationErrorHandler:L111 there is also a::handleError-call

@karser
Copy link
ContributorAuthor

@karser OnDeprecationErrorHandler:L111 there is also a::handleError-call

True. Do we need this autoload juggling? Didn't we already define which ErrorHandler class to use on line 76?

static $autoload = true;$ErrorHandler = class_exists('PHPUnit_Util_ErrorHandler', $autoload) ? 'PHPUnit_Util_ErrorHandler' : 'PHPUnit\Util\ErrorHandler';$autoload = false;

@karserkarserforce-pushed thephpunit83-errorhandler-fix branch from0865fc4 to4e9e3d7CompareAugust 2, 2019 20:20
@karser
Copy link
ContributorAuthor

@smoench Fixed. callPhpUnitErrorHandler is now static so it can be called from set_error_handler closure.

@nicolas-grekasnicolas-grekas added this to the4.3 milestoneAug 2, 2019
Copy link
Contributor

@dominikhajdukdominikhajduk left a comment

Choose a reason for hiding this comment

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

Tested and it solves issue. Thanks!

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedAug 3, 2019
edited
Loading

Not sure how to deal with these booleans. In TestResult class they are all true by default

this is a critical blocker :(

we need to completely redesign the way we hook there to collect deprecations.
until 8.2, phpunit used global state and it was easy to hook, albeit not than clean I realize

now we need to do this in our listener: when TestResult calls startTest in its run method, we need to register phpunit's error handler (duplicating what it does just after the call to startTest) and then add our collector. Then disable at endTest.

Willing to dive there@karser? Maybe with help from@greg0ire too?

Note that we need to do this for 3.4 and for 4.3 (since our code changed so much between the two)

{
$ErrorHandler =self::$utilPrefix.'ErrorHandler';
if (self::$isHandlerInvokable) {
$object =new$ErrorHandler($convertDeprecationsToExceptions =true,$convertErrorsToExceptions =true,$convertNoticesToExceptions =true,$convertWarningsToExceptions =true);
Copy link
Member

Choose a reason for hiding this comment

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

variables$convertDeprecationsToExceptions,$convertErrorsToExceptions are not used and should be omit

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

It was done on purpose because(true, ture, true, true) is not readable. FWIW@nicolas-grekas suggests to move this code to phpunit listener.


if ([self::$utilPrefix.'ErrorHandler','handleError'] ===$oldErrorHandler) {
$handlerMethod =self::$isHandlerInvokable ?'__invoke' :'handleError';
if ([self::$utilPrefix.'ErrorHandler',$handlerMethod] ===$oldErrorHandler) {
Copy link
Member

Choose a reason for hiding this comment

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

if the previous handler is the PhpUnit one, then$oldErrorHandler will contains an instance ofPHPUnit\Util\ErrorHandler

@karser
Copy link
ContributorAuthor

@nicolas-grekas I'm not fully following what happens in phpunit bridge, so I'll ask some stupid questions:

  • Does DeprecationErrorHandler do anything other than collecting deprecations? So it means that DeprecationErrorHandler will be entirely moved to the phpunit listener?
  • There isSymfony\Bridge\PhpUnit\SymfonyTestsListener, so should we use this listener?
  • TestListener interface is deprecated (still works though) in phpunit 8. Should we consider TestHook interface?

@nicolas-grekas
Copy link
Member

Does DeprecationErrorHandler do anything other than collecting deprecations?

it copes only with that responsbility yes

So it means that DeprecationErrorHandler will be entirely moved to the phpunit listener?

It looks like so. Currently, it doesn't need to be registered as a listener, but it looks like phpunit 8 changes that.

There is Symfony\Bridge\PhpUnit\SymfonyTestsListener, so should we use this listener?

I'd say yes, one listener is easier to setup for users

TestListener interface is deprecated (still works though) in phpunit 8. Should we consider TestHook interface?

yes, although it could be done in another PR if that's easier?

@karser
Copy link
ContributorAuthor

@nicolas-grekas Ok, I'll try to do what you described, let's see how far I can get.
Sure, I'll do that in another PR, because this one already solves the problem, though not prefect.

@nicolas-grekas
Copy link
Member

Another alternative might be to check how$convertDeprecationsToExceptions is defined, and maybe duplicate the logic that turns it to true/false. That would be the easiest, if doable.

As of now, I wouldn't recommend merging the PR, as putting all these settings at true is a bug that someone will report sooner than later.

@karser
Copy link
ContributorAuthor

I'll do the research first. Looks like these variables were introduced only in8.3 and didn't exist in8.2

@nicolas-grekas
Copy link
Member

Maybe we can have a look at the stack trace and read the properties from there? It looks like we might find theTestResult instance there, with all the state we need?

@karser
Copy link
ContributorAuthor

TestResult is created by TestRunner which passes $arguments which contain the neccessary parameters.

image

$arguments are created by TestRunner::handleConfiguration. Here is simpllified function which does exactly what we need:

    private function handleConfiguration(array &$arguments): void    {        if (isset($arguments['configuration']) &&            !$arguments['configuration'] instanceof Configuration) {            $arguments['configuration'] = Configuration::getInstance(                $arguments['configuration']            );        }        if (isset($arguments['configuration'])) {            $arguments['configuration']->handlePHPConfiguration();            $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration();            if (isset($phpunitConfiguration['convertDeprecationsToExceptions']) && !isset($arguments['convertDeprecationsToExceptions'])) {                $arguments['convertDeprecationsToExceptions'] = $phpunitConfiguration['convertDeprecationsToExceptions'];            }            if (isset($phpunitConfiguration['convertErrorsToExceptions']) && !isset($arguments['convertErrorsToExceptions'])) {                $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions'];            }            if (isset($phpunitConfiguration['convertNoticesToExceptions']) && !isset($arguments['convertNoticesToExceptions'])) {                $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions'];            }            if (isset($phpunitConfiguration['convertWarningsToExceptions']) && !isset($arguments['convertWarningsToExceptions'])) {                $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions'];            }        }        $arguments['convertDeprecationsToExceptions']                     = $arguments['convertDeprecationsToExceptions'] ?? true;        $arguments['convertErrorsToExceptions']                           = $arguments['convertErrorsToExceptions'] ?? true;        $arguments['convertNoticesToExceptions']                          = $arguments['convertNoticesToExceptions'] ?? true;        $arguments['convertWarningsToExceptions']                         = $arguments['convertWarningsToExceptions'] ?? true;    }

@karserkarserforce-pushed thephpunit83-errorhandler-fix branch 2 times, most recently fromc32c4a4 toede0976CompareAugust 3, 2019 21:56
@karserkarserforce-pushed thephpunit83-errorhandler-fix branch fromede0976 to12717c9CompareAugust 3, 2019 22:01
@karser
Copy link
ContributorAuthor

karser commentedAug 4, 2019
edited
Loading

I extracted this logic into ErrorHandlerCallerV83. It obtains the necessary variables the way PHPUnit does and instantiates ErrorHandler. I made sure that these variables are changed when I modify them in phpunit.xml. it works with both v8.2 and v8.3.
@nicolas-grekas WDYT?

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedAug 4, 2019
edited
Loading

Maybe in another PR to keep this one as is: could you please give a try to the stacktrace-based approach? I feel like it could be simpler and more robust.

@karser
Copy link
ContributorAuthor

karser commentedAug 4, 2019
edited
Loading

Indeed, usingdebug_backtrace is MUCH easier approach. I didn't know that it's possible to get to TestResult object this way. The only issue - what to do if TestResult instance is missing in the stacktrace? Throw an exception then?
image

@nicolas-grekas
Copy link
Member

We should then call the previous handler if one was set, or return false

@karser
Copy link
ContributorAuthor

Here is stacktrace-based PR#32933

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@jderussejderussejderusse left review comments

+1 more reviewer

@dominikhajdukdominikhajdukdominikhajduk left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

4.3

Development

Successfully merging this pull request may close these issues.

6 participants

@karser@smoench@nicolas-grekas@jderusse@dominikhajduk@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp