[PHPUnit] Safe way to check if a class is a Test class#374
[PHPUnit] Safe way to check if a class is a Test class#374TomasVotruba merged 5 commits intomasterfrom
Conversation
|
Do not merge wet, some cases fail if the test class extends a class that actually extends PHPUnit. I'll add tests to ensure that. |
| protected function isInTestClass(Node $node): bool | ||
| { | ||
| $className = (string) $node->getAttribute(Attribute::CLASS_NAME); | ||
| $parentClassName = (string) $node->getAttribute(Attribute::PARENT_CLASS_NAME); |
There was a problem hiding this comment.
@TomasVotruba Do you know any Attribute that indicates all class parents?
There was a problem hiding this comment.
All available Attribute items are in the Attribute class.
This should be resolved by TypeResolver, as it's used only sometimes. So I'd get CLASS_NODE and then get its types.
What do you think?
There was a problem hiding this comment.
@TomasVotruba Do you have an example of TypeResolver that I can study and update this PR?
| protected function isInTestClass(Node $node): bool | ||
| { | ||
| $className = (string) $node->getAttribute(Attribute::CLASS_NAME); | ||
| $parentClassName = (string) $node->getAttribute(Attribute::PARENT_CLASS_NAME); |
There was a problem hiding this comment.
All available Attribute items are in the Attribute class.
This should be resolved by TypeResolver, as it's used only sometimes. So I'd get CLASS_NODE and then get its types.
What do you think?
| * Check if the file is a PHPUnit TestCase. By default, it should end with "Test", as it is the standard. | ||
| * | ||
| * @see https://phpunit.de/getting-started-with-phpunit.html | ||
| */ |
There was a problem hiding this comment.
Why removing this?
What if sb will come and try to analyze nodes (much worse performance) instead of simple and fast PHPUnit approach.
There was a problem hiding this comment.
Because I test Rector against an application that didn't follow this rule, plus, all its test classes extends a based one :(
There was a problem hiding this comment.
I see.
Failing test would tell this for itself. What about that?
| protected function isInTestClass(Node $node): bool | ||
| { | ||
| $className = (string) $node->getAttribute(Attribute::CLASS_NAME); | ||
| $nodeTypeResolver = new NodeTypeResolver(); |
There was a problem hiding this comment.
@TomasVotruba Should we revert #300? Because doing this way, isn't working by our CS :(
There was a problem hiding this comment.
@TomasVotruba ping.
Is there a way to DI without __construct? If not, revert #300 will be the solution (unfortunately)
There was a problem hiding this comment.
I missed this, sorry.
You can inject dependency as in Abstract class:
rector/src/Rector/AbstractRector.php
Lines 20 to 48 in 9f4ca80
That's Symfony approach to this
|
Finally done, we can now merge it 🎉 |
TomasVotruba
left a comment
There was a problem hiding this comment.
Just one detail and it's ready to merge
| $nodeResolved = $this->nodeTypeResolver->resolve($node); | ||
|
|
||
| return Strings::endsWith($className, 'Test'); | ||
| return ! array_intersect([TestCase::class, 'PHPUnit_Framework_TestCase'], $nodeResolved); |
There was a problem hiding this comment.
What happens, if sb installs a Rector but doesn't have PHPUnit with TestCase class installed?
There was a problem hiding this comment.
I didn’t get it :(
Without TestCase isn’t possible to execute tests, is?
There was a problem hiding this comment.
Well, somebody can use PHPUnit_Framework_TestCase, right?
There was a problem hiding this comment.
We are checking it, aren't we? 🤔
return ! array_intersect([TestCase::class, 'PHPUnit_Framework_TestCase'], $nodeResolved);There was a problem hiding this comment.
Yes, but that depends on PHPUnit\Framework\TestCase class to exist. And it does in our code so it works.
Sb might download Rector and have only PHPUnit_Framework_TestCase in their code.
So PHPUnit\FrameworkTestCase will end up as un-existing class error.
That's why it should string here.
There was a problem hiding this comment.
So I'll ignore this file from our CS. I used ::class here because CS complained about it
|
Awesome, thank you 👍 |
rectorphp/rector-src@ae71516 cleanup unused fixtures (#374)
The current logic checks if the TestCase ends with
Test, but this isn't the safest way to do it. For example: