Skip to content

Commit adb831d

Browse files
authored
[CodeQuality] Add SingleWithConsecutiveToWithRector (#370)
* register rule to code quality set * [CodeQuality] Add SingleWithConsecutiveToWithRector
1 parent 62500b9 commit adb831d

File tree

8 files changed

+217
-0
lines changed

8 files changed

+217
-0
lines changed

config/sets/phpunit-code-quality.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\AssertSameBoolNullToSpecificMethodRector;
2727
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\AssertSameTrueFalseToAssertTrueFalseRector;
2828
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\AssertTrueFalseToSpecificMethodRector;
29+
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\NarrowIdenticalWithConsecutiveRector;
2930
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\RemoveExpectAnyFromMockRector;
31+
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector;
3032
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\UseSpecificWillMethodRector;
3133
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\UseSpecificWithMethodRector;
3234

@@ -43,6 +45,10 @@
4345
AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRector::class,
4446
DataProviderArrayItemsNewLinedRector::class,
4547

48+
// narrow with consecutive
49+
NarrowIdenticalWithConsecutiveRector::class,
50+
SingleWithConsecutiveToWithRector::class,
51+
4652
// specific asserts
4753
AssertCompareOnCountableWithMethodToAssertCountRector::class,
4854
AssertCompareToSpecificMethodRector::class,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector\Source\SomeMockedClass;
7+
8+
final class RepeatedSame extends TestCase
9+
{
10+
public function test()
11+
{
12+
$someServiceMock = $this->createMock(SomeMockedClass::class);
13+
$someServiceMock->expects($this->exactly(3))
14+
->method('prepare')
15+
->withConsecutive(
16+
[1],
17+
);
18+
}
19+
}
20+
21+
?>
22+
-----
23+
<?php
24+
25+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector\Fixture;
26+
27+
use PHPUnit\Framework\TestCase;
28+
use Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector\Source\SomeMockedClass;
29+
30+
final class RepeatedSame extends TestCase
31+
{
32+
public function test()
33+
{
34+
$someServiceMock = $this->createMock(SomeMockedClass::class);
35+
$someServiceMock->expects($this->exactly(3))
36+
->method('prepare')
37+
->with(
38+
[1],
39+
);
40+
}
41+
}
42+
43+
?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\NarrowIdenticalWithConsecutiveRector\Source\SomeMockedClass;
7+
8+
final class SkipMultipleValues extends TestCase
9+
{
10+
public function test()
11+
{
12+
$someServiceMock = $this->createMock(SomeMockedClass::class);
13+
$someServiceMock->expects($this->exactly(3))
14+
->method('prepare')
15+
->withConsecutive(
16+
[1],
17+
[2],
18+
);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class SingleWithConsecutiveToWithRectorTest 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,7 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector\Source;
4+
5+
class SomeMockedClass
6+
{
7+
}
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\PHPUnit\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->rule(SingleWithConsecutiveToWithRector::class);
10+
};

rules/CodeQuality/Rector/MethodCall/NarrowIdenticalWithConsecutiveRector.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1616
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
1717

18+
/**
19+
* @see \Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\NarrowIdenticalWithConsecutiveRector\NarrowIdenticalWithConsecutiveRectorTest
20+
*/
1821
final class NarrowIdenticalWithConsecutiveRector extends AbstractRector
1922
{
2023
public function __construct(
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\CodeQuality\Rector\MethodCall;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Arg;
9+
use PhpParser\Node\Expr\MethodCall;
10+
use PhpParser\Node\Expr\StaticCall;
11+
use PhpParser\Node\Identifier;
12+
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
13+
use Rector\Rector\AbstractRector;
14+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
15+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
16+
17+
/**
18+
* @see \Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\SingleWithConsecutiveToWithRector\SingleWithConsecutiveToWithRectorTest
19+
*/
20+
final class SingleWithConsecutiveToWithRector extends AbstractRector
21+
{
22+
public function __construct(
23+
private readonly TestsNodeAnalyzer $testsNodeAnalyzer
24+
) {
25+
}
26+
27+
public function getRuleDefinition(): RuleDefinition
28+
{
29+
return new RuleDefinition(
30+
'Change single withConsecutive() to with() call',
31+
[
32+
new CodeSample(
33+
<<<'CODE_SAMPLE'
34+
use PHPUnit\Framework\TestCase;
35+
36+
final class SomeTest extends TestCase
37+
{
38+
public function run()
39+
{
40+
$this->personServiceMock->expects($this->exactly(3))
41+
->method('prepare')
42+
->withConsecutive(
43+
[1],
44+
);
45+
}
46+
}
47+
CODE_SAMPLE
48+
,
49+
<<<'CODE_SAMPLE'
50+
use PHPUnit\Framework\TestCase;
51+
52+
final class SomeTest extends TestCase
53+
{
54+
public function run()
55+
{
56+
$this->personServiceMock->expects($this->exactly(3))
57+
->method('prepare')
58+
->with([1]);
59+
}
60+
}
61+
CODE_SAMPLE
62+
),
63+
]
64+
);
65+
}
66+
67+
/**
68+
* @return array<class-string<MethodCall|StaticCall>>
69+
*/
70+
public function getNodeTypes(): array
71+
{
72+
return [MethodCall::class];
73+
}
74+
75+
/**
76+
* @param MethodCall|StaticCall $node
77+
*/
78+
public function refactor(Node $node): MethodCall|StaticCall|null
79+
{
80+
if (! $this->testsNodeAnalyzer->isInTestClass($node)) {
81+
return null;
82+
}
83+
84+
if (! $this->isName($node->name, 'withConsecutive')) {
85+
return null;
86+
}
87+
88+
if (count($node->getArgs()) !== 1) {
89+
return null;
90+
}
91+
92+
$firstArg = $node->getArgs()[0];
93+
94+
// use simpler with() instead
95+
$node->name = new Identifier('with');
96+
$node->args = [new Arg($firstArg->value)];
97+
98+
return $node;
99+
}
100+
}

0 commit comments

Comments
 (0)