-
-
Notifications
You must be signed in to change notification settings - Fork 57
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
Generic/ForLoopShouldBeWhileLoop: improve sniff code coverage + fix potential PHP 8.3 deprecation notice #226
Generic/ForLoopShouldBeWhileLoop: improve sniff code coverage + fix potential PHP 8.3 deprecation notice #226
Conversation
Doing this to be able to create a test with a syntax error on a separate file.
@rodrigoprimo Thanks for continuing your work on these type of PRs.
👍🏻 As I'm looking over your shoulder at the tests now anyway, may I suggest adding some tests with a
I don't have an answer for that. You may be able to find more info on the website of the original PMD project on which the PHP Mess Detector is based. Alternatively, maybe @manuelpichler remembers ? Or one of the current maintainers of the PHPMD project, like @tvbeek, could advise ?
Good catch and yes, most definitely! If for no other reason than that the current code will throw a "Decrement on type null has no effect, this will change in the next major version of PHP" deprecation notice on PHP 8.3. I guess, I don't need to ask you to add a test for that too ? 😉
For the future - I appreciate you adding these links, but they are not needed. Each PR contains a direct link to the Coveralls report in the status check block (and I check PRs locally anyway): |
For PHPMD we have a rule about CyclomaticComplexity ( https://phpmd.org/rules/codesize.html#cyclomaticcomplexity ) but not anything about the |
Thanks for checking this PR, @jrfnl.
Sure, I just added a new commit with a few tests using the alternative syntax.
Thanks for your input, @tvbeek. @jrfnl, I defer to you on whether or not it makes sense to change the sniff, on a separate PR, to trigger a warning when it finds
I added the test for that case. Would you like me to work on fixing the sniff as well? In a separate PR?
👍 |
@jrfnl, and here is the warning that you mentioned that is causing the tests to fail when running PHP 8.3: https://github.com/PHPCSStandards/PHP_CodeSniffer/actions/runs/7410876425/job/20164113044?pr=226#step:9:57. I failed to consider that this would obviously happen before posting my previous comment. Let me know if you prefer that I fix the sniff in this PR or remove the test from it and add it together with the fix on a separate PR (that is, if you want me to work on this fix). |
Just documenting here that the sniff ForLoopWithTestFunctionCall will also throw a "Decrement on type null has no effect, this will change in the next major version of PHP" deprecation notice on PHP 8.3 if the closing parenthesis is missing. |
Let's leave that out of this PR for now, if for no other reason than that that change would need to go in a minor release while this PR as-is can go into a patch release. You might want to open an issue to see if other people are interested in this change ?
I'm perfectly fine with you fixing it in this PR, preferably the test and the fix should be in the same commit though, so this PR would then ideally be three commits:
Sounds like a nice one for you to tackle next once this one is finished ;-) |
src/Standards/Generic/Tests/CodeAnalysis/ForLoopShouldBeWhileLoopUnitTest.3.inc
Outdated
Show resolved
Hide resolved
This commit adds the following groups of tests: - A few tests that do not trigger the sniff but should help to protect against regressions in the future. Including tests using the for loop alternative syntax. - A test to exercise code in the sniff to bail early if the `for` keyword is found without a opening parenthesis. This part was not covered before.
8ad4ea5
to
be494bf
Compare
Sure, here is the issue: #230
Done, this PR is ready to be reviewed again. Thanks.
Sounds good :-) |
src/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php
Outdated
Show resolved
Hide resolved
src/Standards/Generic/Tests/CodeAnalysis/ForLoopShouldBeWhileLoopUnitTest.3.inc
Outdated
Show resolved
Hide resolved
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.
Thanks for making those updates @rodrigoprimo ! LGTM.
Two practical points:
- Could you squash those last two commits into the PHP 8.3 fix commit ?
- As this PR now contains a small bugfix, the "Changelog" section in the PR template could be brought back.
You don't need to worry about that, I'll come up with something, but maybe something to keep in mind for the future.
This commit fixes an issue in the sniff that could result in the following E_DEPRECATED error when running PHP 8.3: ``` Decrement on type null has no effect, this will change in the next major version of PHP src/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php:65 ``` This sniff relies on finding the position of the open and closing parentheses for a given `for` loop. However, the problem was that there was no defensive code for cases when the closing parenthesis is missing. The sniff would still work when running PHP >= 8.2, but on PHP 8.3 it would throw the deprecated message above. This would happen because since there is no closing parenthesis `$end` is set to null, and $next <= $end always evaluates to false (https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/84acf4e56f110db8e75cb9a575c5727df637643c/src/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php#L74). The issue was fixed by bailing early if the closing parenthesis is missing. A test with a `for` loop without the closing parenthesis was added.
ccad790
to
1ebc09e
Compare
Sure, I just did it.
This answers the question that I asked in #235 (I should probably have asked it here instead) :-) Thanks for taking care of the changelog. |
Description
This PR improves the code coverage for the Generic/ForLoopShouldBeWhileLoop sniff.
There was just one block of code that was not covered by tests. It is a defensive code that bails early if the
for
keyword is not followed by an opening parenthesis. I also added a few more test cases that were already handled properly by the sniff, but they seemed different enough from the other test cases to justify their inclusion to avoid regressions in the future.Two questions that occurred to me while working on this PR:
One of the test cases that I added is
for (;;)
. This could be replaced withwhile
as well, but I'm not sure if the sniff is not covering this case intentionally or not. Should we update the sniff to trigger a warning forfor(;;)
or leave it as is? Judging by the commit message that introduced this sniff, it seems it was inspired by a PHP Mess Detector rule, but I was not able to find such a rule to check how it handlesfor (;;)
.The sniff relies on finding the closing parenthesis associated with the
for
keyword. But there is no code to explicitly handle missing closing parenthesis. The sniff still works as without the closing parenthesis,$end
isnull
, and$next <= $end
always evaluates to false. I wonder if we should update the sniff to bail early if there is no closing parenthesis?Code coverage for the Generic/ForLoopShouldBeWhileLoop sniff before this PR:
https://coveralls.io/builds/64633852/source?filename=src%2FStandards%2FGeneric%2FSniffs%2FCodeAnalysis%2FForLoopShouldBeWhileLoopSniff.php
And after this PR:
https://coveralls.io/builds/64858806/source?filename=src%2FStandards%2FGeneric%2FSniffs%2FCodeAnalysis%2FForLoopShouldBeWhileLoopSniff.php
Related issues/external references
Part of #146
Types of changes
PR checklist