Closed (fixed)
Project:
Drupal core
Version:
10.3.x-dev
Component:
phpunit
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
14 Feb 2024 at 16:08 UTC
Updated:
3 Jul 2024 at 13:44 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
mstrelan commentedWe should be able to use AddVoidReturnTypeWhereNoReturnRector for this, I'll give it a try.
There may also be a phpcs sniff we can use instead which would allow us to add to the existing ruleset.
Comment #3
mstrelan commentedAlso found VoidReturnFixer for PHP-CS-Fixer but nothing yet for phpcs.
Comment #5
mstrelan commentedAdded first attempt of an MR generated with PHP-CS-Fixer, added steps to reproduce.
Comment #6
mstrelan commented[ERROR] Found 121 errors
Comment #7
mstrelan commentedHave resolved all the phpstan issues. Here's the diff of changes since running php-cs-fixer.
We now have a small number of errors and test failures to resolve.
Comment #8
mstrelan commentedPossibly we should have attempted to limit this to functions with the
testprefix but I'm not sure that's possible to automate. Tests are passing now, so this is over for review and deliberation about how this could be handled or, dare I say, split.Comment #9
acbramley commentedI scanned majority of the MR (up to image module). 90-95% of the changes are just test case functions. The remaining are things like setUpContentType, anonymous/inline callbacks and doAssert style functions. If it's not automatable to restrict to just test cases I'd vote for just including everything in all test files to avoid a lot of manual work.
This could be split up, but I won't comment on if it should or not :D
I also separately reviewed https://git.drupalcode.org/issue/drupal-3421418/-/compare/981d4f6368d4ff... and those changes make sense to me.
However, I'm not sure why we can't add it to EntityResourceTestBase::testPost?
For me this looks good to go, nice work @mstrelan
Comment #10
mstrelan commentedThanks for the review. Have fixed
EntityResourceTestBase::testPost. For some reason\Drupal\Tests\entity_test\Functional\Rest\EntityTestComputedFieldNormalizerTest::testPostdid not initially have void added and that made phpstan sad. Instead I've just added void to both methods.Comment #11
acbramley commentedNice, I'm gonna mark RTBC to see if anyone thinks it should be split up :)
Comment #13
mstrelan commentedI've found a way to apply this only to test* methods by using rector and hacking the
\Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector::shouldSkipClassMethodmethod with this:Then using a rector.php file:
And finally:
Have created a separate MR for this so we can discuss which route we want to take here.
Comment #14
mstrelan commentedUpdated IS with the two approaches and remaining tasks
Comment #15
smustgrave commentedBoth MRs appear to be unmergable.
As much as I like the all in one, this could touch 1000s of files and be difficult to review. Should it be broken up?
Comment #16
mondrakeMy 0.02:
Only methods with test prefix. The other methods may be used by contrib/custom and their (non)value used and therefore fail PHPStan. Also forcing a
voidseems a too strong assumption.One big megapatch, in an agreed date during the beta window. Probably needs release manager review to assign a date.
Comment #17
mondrakeComment #18
longwaveThanks for the work so far!
Correct, this is non critical cleanup, so to avoid disrupting other issues we are better off doing this in one hit, but we have to time it for least disruption. It's a bit tricky because release dates are up in the air, depending on when we complete Drupal 11 beta requirements: https://www.drupal.org/about/core/policies/core-release-cycles/schedule
May 2024 covers all three windows so I think a vague date of that is worth adding for now, as we get closer to the time we can revive this and get it ready to commit again.
Comment #19
longwaveAdded to #3284879: [meta] Requirements for tagging Drupal 11.0.0-beta1 so we have less chance of forgetting.
Comment #20
mstrelan commentedAssuming the current plan would be to work on this after the alpha. We should probably also postpone this on #3427999: [PHP 8.4] Fix implicitly nullable type declarations since that will touch a lot of the same methods.
Comment #22
mstrelan commentedWell it's May 2024 so maybe we should pick this back up. I've updated the IS, rebased MR 6606 and hidden 6604. Unless we want to postpone this on #3427999: [PHP 8.4] Fix implicitly nullable type declarations then this is ready for review.
Comment #23
smustgrave commented1000+ files is hard to review and crashes gitlab
But the 1 to 1 code addition to subtraction does indicate nothing more was added.
Been trying to help tickets I review by adding :void to tests (nitpicky stuff) but still large number here.
Spot checking the files I don't see anything off and tests are still green.
Believe this is good.
Comment #24
mstrelan commentedYeah for these massive diffs I find it easier to review the raw diff than the formatted one. You could probably also
grepandwc -lfor the numbers of lines with) {and the number with): void {. Can also grep those to see if they start with- function testand+ function testComment #25
mstrelan commentedHad to rebase again. I then put together the following commands to review the changes:
Generate patch with 0 lines of context, excluding all the git noise.
Count the lines of the patch adding :void to the end of a test function and ensure it matches the number of lines removing a test function.
Find any remaining differences:
These changes are found in the following places:
\Drupal\Tests\jsonapi\Functional\CommentTest::testPatchIndividual- can't return a void function\Drupal\FunctionalJavascriptTests\Ajax\AjaxTest- not sure why this wasn't failing cspell already\Drupal\Tests\Component\Annotation\Doctrine\DocParserTest::testSyntaxErrorWithUnknownCharacters- maybe we should exclude doctrine annotations here?Setting NW because I think we should exclude
\Drupal\Tests\Component\Annotation\Doctrine.Comment #26
mstrelan commentedRebased, which has removed the need for the cspell ignore, and reverted the change to doctrine tests.
Reran the commands in #25 and end up with the following:
Comment #27
smustgrave commentedSeems to still need a rebase. May be one of those things will need to rebase, immediately review, and have a committer ready
Comment #28
longwaveThis will need enough MRs to apply to all active branches - 11.x, 11.0.x, 10.4.x and 10.3.x - as we need to commit it everywhere to keep things in sync.
Comment #40
mstrelan commentedI have hidden all the existing MRs and added new ones from 11.x, 11.0.x, 10.4.x and 10.3.x. Have run the checks in #25 and the only change that isn't just adding
: voidis changingCommentTest::testPatchIndividualto not return anything.Comment #41
xjmI began reviewing this with a porcelain diff. PHP script to parse the diff in my home directory:
Steps:
This flagged exactly one change that isn't exactly adding
: voidsomewhere, which I located to be the following hunk incore/modules/jsonapi/tests/src/Functional/CommentTest.php:I suppose this is necessary because without removing the
return, it would break the contract of thevoidreturn typehint.Ideally, that change would have been fixed in a separate issue; however, given the scope and urgency of this, and that it's just a one-off, I'll let it slide. :)
Later, I'll make the porcelain-parsing script a little more robust to ensure the added
: voidis actually a function typehint, but for now, I'll check the other MRs. :)Comment #42
xjmI confirmed the 11.0.x, 10.4.x, and 10.3.x merge requests also have that one outlying change. Now I'll tweak the script to add a hunk validating that the
: voidadditions are in fact test typehints, and repeat.Comment #43
xjmImproved script validating that these are all correctly placed
voidtypehints on test methods:Next I'll validate that only test files are changed.
Comment #44
xjmChecked the file list next. Steps after applying the patch:
That script simply being:
This has flagged what I think is actually an out-of-scope change?
TestControllersappears to be a test fixture used by various routing system tests that just has some really terribly named route callbacks. For example, the abovetest24()is used incore/modules/system/tests/modules/router_test_directory/router_test.routing.yml:This is used in
core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php:So it's not a test method at all.
That said, it's not wrong for it to have a void typehint. It does, after all, return void. But did this get lumped in because of greppiness, or because of static analysis? If the latter, we might have a problem. If the former, let's just remove those two hunks from the MRs.
Tagging "Needs followup" to fix the absolutely terrible routing test fixture naming.
Comment #45
xjmComment #46
mstrelan commentedReverted the changes to TestControllers and opened #3455287: Rename \Drupal\router_test\TestControllers and its methods. Removing tag for follow up.
Comment #47
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #48
longwaveComment #49
smustgrave commentedGoing to remark as tests are green and these seem like MRs that will always have conflicts so may be nice to get this chunk in. But testControllers appear reverted.
Comment #50
xjmI was only halfway through my review. I'd addressed that the MR didn't contain anything it shouldn't, but not that it did contain everything it should. With a very large MR like this, there are a lot of strategies to use (the simplest being a local
git diff --staged --color-wordsfor example), but we should use some of them because we need our peer reviewers to help catch issues. Simply verifying that all a committer's feedback has been addressed isn't really sufficient on its own for an issue to be RTBC, unless everything else already was RTBC with actual peer review, and it wasn't here.Setting NR, and I'll continue to work on it. Thanks!
Comment #51
xjmI rechecked the updated MRs with #41 - #44, and confirmed that the issue with the routing controller is resolved without any additional malformed changes being introduced.
Next going to do some grepping to look for stragglers.
Comment #52
xjmNext, I reviewed all places where a function with a name starting with "test" in the core tests (not module tests yet) was missing a return typehint. My grep was pretty basic to cast a wide net:
grep -r "function test" core/tests/* | grep ") {" > ~/tmp.txt(Then deduplicated and parsed out the filenames from that file using emacs macros, and opened all the listed files to look at the matches in context.)
Three categories of thing:
Stuff that looks to be fixtures
fixtures/test_stable/test_stable.themeDrupal/Tests/Core/Form/fixtures/form_base_test.incDrupal/Tests/Core/Database/Stub/StubConnection.phpFixture global function being written out to the filesystem:
Global functions I assume to be fixtures added outside the test class in
EntityResolverManagerTest:Stuff that actually has return values
Should we have a followup to research test methods with return values and determine if they're intentional or not?
In
ProxyBuilderTest:Returns a thing (might merit a closer looksee).
In
UrlTest:It returns
$urls.In
KeyValueEntityStorageTestandConfigEntityStorageTestthere are some identical methods with return values:All return the entity.
In
FormStateTest:Other
In
StaticReflectionParserTest:Excluded for being the Doctrine fork, I guess.
I don't totally understand what this is, but it's in
ExternalCommandRequirementTest.UpdatePathTestBase:This doesn't actually seem to return anything. I notice that the method is protected. Not sure what's going on with this one.
Comment #53
xjmThe list from module tests is fortunately shorter.
Fixtures
Outside the actual test class in
PathPluginBaseTest:Things that actually return stuff
Both
DateFormatAccessControlHandlerTestandMenuAccessControlHandlerTesthave an undocumented test method which returns a massive access result array:public static function testAccessProvider() {Looking more closely, this is just a mis-named data provider for the properly typehinted
testAccess()method, so merits its own issue to fix.In
JsonApiDocumentTopLevelNormalizerTest:This one is another mis-named data provider.
Other
Commented-out code in
ArgumentDefaultTest:(A followup should be filed, either to add the test or just to remove the issue-less @todo.)
In
FileUploadTest:None of these actually return anything. They are protected methods. They're called as helpers from e.g.
testInvalidFileUploads().For completeness' sake, I'll also look through theme and profile tests etc., then sort through what needs followups vs. things we might want to look at here.
Comment #54
xjmcore/profiles/demo_umami/tests/src/Functional/DemoUmamiProfileTest.phphas another protected helper that was not included but does return void:Comment #55
xjmOK, based on the above, here's what I recommend:
testSomething()despite being protected; the usual pattern isassertSomething()).For this issue, I'd like to understand these two things before commit:
I'll get to work on the followups, starting with the first one,
Comment #56
xjmThat's all the proposed followups filed.
Comment #57
mstrelan commentedRe: #55
ExternalCommandRequirementTest was removed from 11.x in #3425660: [11.x] Remove deprecated ExternalCommandRequirementsTrait so I think we can leave it as it is in 10.3 and 10.4
UpdatePathTestBase::testDatabaseLoaded is a protected helper method called from UpdatePathTestBaseFilledTest and UpdatePathTestBaseTest so I think it should be addressed in #3455549: Add return typehints to protected test helper methods.
Comment #58
xjmI re-reviewed the 11.x MR with the same steps as I used in #51 - #54 with the 10.3.x MR, and confirmed that there are no additional weirdnesses aside from things we've already explained and/or scoped to followups.
So I think it's RTBC!
Comment #61
catchCommitted/pushed to 11.x, 11.0.x, 10.4.x, 10.3.x respectively thanks!
I could not get commit checks to actually complete on commit, so ended up committing all four patches with --no-verify. Given this doesn't yet introduce the phpcs rule, that ought to be OK, hopefully we don't find out it wasn't.
Comment #67
catchComment #68
catch