Skip to content

Commit b805102

Browse files
authored
[typed-collections] Add AssertNullOnCollectionToAssertEmptyRector (#423)
1 parent fb07dc4 commit b805102

6 files changed

Lines changed: 191 additions & 0 deletions

File tree

config/sets/typed-collections.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Rector\Doctrine\TypedCollections\Rector\FuncCall\InArrayOnCollectionToContainsCallRector;
2727
use Rector\Doctrine\TypedCollections\Rector\If_\RemoveIfInstanceofCollectionRector;
2828
use Rector\Doctrine\TypedCollections\Rector\If_\RemoveIsArrayOnCollectionRector;
29+
use Rector\Doctrine\TypedCollections\Rector\MethodCall\AssertNullOnCollectionToAssertEmptyRector;
2930
use Rector\Doctrine\TypedCollections\Rector\MethodCall\SetArrayToNewCollectionRector;
3031
use Rector\Doctrine\TypedCollections\Rector\New_\RemoveNewArrayCollectionWrapRector;
3132
use Rector\Doctrine\TypedCollections\Rector\NullsafeMethodCall\RemoveNullsafeOnCollectionRector;
@@ -80,5 +81,6 @@
8081

8182
// cleanup
8283
RemoveNullsafeOnCollectionRector::class,
84+
AssertNullOnCollectionToAssertEmptyRector::class,
8385
]);
8486
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\MethodCall\AssertNullOnCollectionToAssertEmptyRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class AssertNullOnCollectionToAssertEmptyRectorTest extends AbstractRectorTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
}
18+
19+
public static function provideData(): Iterator
20+
{
21+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22+
}
23+
24+
public function provideConfigFilePath(): string
25+
{
26+
return __DIR__ . '/config/configured_rule.php';
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\MethodCall\AssertNullOnCollectionToAssertEmptyRector\Fixture;
4+
5+
use Doctrine\Common\Collections\Collection;
6+
use PHPUnit\Framework\TestCase;
7+
8+
final class AssertNullOnCollection extends TestCase
9+
{
10+
public Collection $items;
11+
12+
public function someMethod()
13+
{
14+
$this->assertNull($this->items);
15+
}
16+
}
17+
18+
?>
19+
-----
20+
<?php
21+
22+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\MethodCall\AssertNullOnCollectionToAssertEmptyRector\Fixture;
23+
24+
use Doctrine\Common\Collections\Collection;
25+
use PHPUnit\Framework\TestCase;
26+
27+
final class AssertNullOnCollection extends TestCase
28+
{
29+
public Collection $items;
30+
31+
public function someMethod()
32+
{
33+
$this->assertEmpty($this->items);
34+
}
35+
}
36+
37+
?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\MethodCall\AssertNullOnCollectionToAssertEmptyRector\Fixture;
4+
5+
use Doctrine\Common\Collections\Collection;
6+
use PHPUnit\Framework\TestCase;
7+
8+
final class SkipAssertNullOnAnythingElse extends TestCase
9+
{
10+
public $items;
11+
12+
public function someMethod()
13+
{
14+
$this->assertNull($this->items);
15+
}
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use Rector\Doctrine\TypedCollections\Rector\MethodCall\AssertNullOnCollectionToAssertEmptyRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->rule(AssertNullOnCollectionToAssertEmptyRector::class);
10+
};
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Doctrine\TypedCollections\Rector\MethodCall;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\MethodCall;
9+
use PhpParser\Node\Identifier;
10+
use Rector\Doctrine\TypedCollections\TypeAnalyzer\CollectionTypeDetector;
11+
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
12+
use Rector\Rector\AbstractRector;
13+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
14+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
15+
16+
/**
17+
* @see \Rector\Doctrine\Tests\TypedCollections\Rector\MethodCall\AssertNullOnCollectionToAssertEmptyRector\AssertNullOnCollectionToAssertEmptyRectorTest
18+
*/
19+
final class AssertNullOnCollectionToAssertEmptyRector extends AbstractRector
20+
{
21+
public function __construct(
22+
private readonly TestsNodeAnalyzer $testsNodeAnalyzer,
23+
private readonly CollectionTypeDetector $collectionTypeDetector
24+
) {
25+
}
26+
27+
public function getRuleDefinition(): RuleDefinition
28+
{
29+
return new RuleDefinition(
30+
'Change $this->assertNull() on Collection object to $this->assertEmpty() in tests',
31+
[
32+
new CodeSample(
33+
<<<'CODE_SAMPLE'
34+
use Doctrine\Common\Collections\Collection;
35+
36+
final class SomeClass extends \PHPUnit\Framework\TestCase
37+
{
38+
private Collection $items;
39+
40+
public function test(): void
41+
{
42+
$this->assertNull($this->items);
43+
}
44+
}
45+
CODE_SAMPLE
46+
,
47+
<<<'CODE_SAMPLE'
48+
use Doctrine\Common\Collections\Collection;
49+
50+
final class SomeClass extends \PHPUnit\Framework\TestCase
51+
{
52+
private Collection $items;
53+
54+
public function test(): void
55+
{
56+
$this->assertEmpty($this->items);
57+
}
58+
}
59+
CODE_SAMPLE
60+
)]
61+
);
62+
}
63+
64+
public function getNodeTypes(): array
65+
{
66+
return [MethodCall::class];
67+
68+
}
69+
70+
/**
71+
* @param MethodCall $node
72+
*/
73+
public function refactor(Node $node): MethodCall|null
74+
{
75+
if ($node->isFirstClassCallable()) {
76+
return null;
77+
}
78+
79+
if (! $this->isName($node->name, 'assertNull')) {
80+
return null;
81+
}
82+
83+
if (! $this->testsNodeAnalyzer->isInTestClass($node)) {
84+
return null;
85+
}
86+
87+
$firstArg = $node->getArgs()[0];
88+
89+
if (! $this->collectionTypeDetector->isCollectionType($firstArg->value)) {
90+
return null;
91+
}
92+
93+
// rename
94+
$node->name = new Identifier('assertEmpty');
95+
96+
return $node;
97+
}
98+
}

0 commit comments

Comments
 (0)