Skip to content

Commit 85797b5

Browse files
committed
[CodeQuality] Add WillReturnCallbackFallbackToThrowRector to throw on unexpected extra consecutive call
1 parent b9985d8 commit 85797b5

14 files changed

Lines changed: 339 additions & 9 deletions

File tree

config/sets/phpunit-code-quality.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@
8787
NarrowSingleWillReturnCallbackRector::class,
8888
SingleWithConsecutiveToWithRector::class,
8989

90+
// enable once better tested
91+
// WillReturnCallbackFallbackToThrowRector::class,
92+
9093
// type declarations
9194
TypeWillReturnCallableArrowFunctionRector::class,
9295
StringCastAssertStringContainsStringRector::class,

config/sets/phpunit-mock-to-stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
use Rector\Config\RectorConfig;
66
use Rector\PHPUnit\CodeQuality\Rector\Class_\AddIntersectionVarToMockObjectPropertyRector;
7-
use Rector\PHPUnit\CodeQuality\Rector\ClassMethod\BareCreateMockAssignToDirectUseRector;
87
use Rector\PHPUnit\CodeQuality\Rector\Class_\AddStubIntersectionVarToStubPropertyRector;
8+
use Rector\PHPUnit\CodeQuality\Rector\ClassMethod\BareCreateMockAssignToDirectUseRector;
99
use Rector\PHPUnit\PHPUnit120\Rector\CallLike\CreateStubInCoalesceArgRector;
1010
use Rector\PHPUnit\PHPUnit120\Rector\CallLike\CreateStubOverCreateMockArgRector;
1111
use Rector\PHPUnit\PHPUnit120\Rector\Class_\PropertyCreateMockToCreateStubRector;

config/sets/phpunit100.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
// https://github.com/sebastianbergmann/phpunit/pull/3687
7777
new MethodCallRename('PHPUnit\Framework\MockObject\MockBuilder', 'setMethods', 'onlyMethods'),
7878

79-
//https://github.com/sebastianbergmann/phpunit/issues/5062
79+
// https://github.com/sebastianbergmann/phpunit/issues/5062
8080
new MethodCallRename('PHPUnit\Framework\TestCase', 'expectDeprecationMessage', 'expectExceptionMessage'),
8181
new MethodCallRename(
8282
'PHPUnit\Framework\TestCase',

ecs.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Symplify\EasyCodingStandard\Config\ECSConfig;
66

77
return ECSConfig::configure()
8-
->withPreparedSets(psr12: true, common: true, symplify: true)
8+
->withPreparedSets(psr12: true, common: true)
99
->withPaths([
1010
__DIR__ . '/src',
1111
__DIR__ . '/rules',
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WillReturnCallbackFallbackToThrowRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class SkipFallbackReturn extends TestCase
8+
{
9+
public function test()
10+
{
11+
$matcher = $this->exactly(2);
12+
13+
$someServiceMock = $this->createMock(SomeMockedClass::class);
14+
$someServiceMock->expects($matcher)
15+
->method('run')
16+
->willReturnCallback(function () use ($matcher) {
17+
if ($matcher->numberOfInvocations() === 1) {
18+
return 'first';
19+
}
20+
21+
if ($matcher->numberOfInvocations() === 2) {
22+
return 'second';
23+
}
24+
25+
return 'third';
26+
});
27+
}
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WillReturnCallbackFallbackToThrowRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class SkipNoMatcherBranch extends TestCase
8+
{
9+
public function test()
10+
{
11+
$matcher = $this->exactly(1);
12+
13+
$someServiceMock = $this->createMock(SomeMockedClass::class);
14+
$someServiceMock->expects($matcher)
15+
->method('run')
16+
->willReturnCallback(function () use ($matcher) {
17+
return 'value';
18+
});
19+
}
20+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WillReturnCallbackFallbackToThrowRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class VoidFallback extends TestCase
8+
{
9+
public function test()
10+
{
11+
$matcher = $this->exactly(1);
12+
13+
$someServiceMock = $this->createMock(SomeMockedClass::class);
14+
$someServiceMock->expects($matcher)
15+
->method('run')
16+
->willReturnCallback(function () use ($matcher) {
17+
if ($matcher->numberOfInvocations() === 1) {
18+
return 'first';
19+
}
20+
});
21+
}
22+
}
23+
24+
?>
25+
-----
26+
<?php
27+
28+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WillReturnCallbackFallbackToThrowRector\Fixture;
29+
30+
use PHPUnit\Framework\TestCase;
31+
32+
final class VoidFallback extends TestCase
33+
{
34+
public function test()
35+
{
36+
$matcher = $this->exactly(1);
37+
38+
$someServiceMock = $this->createMock(SomeMockedClass::class);
39+
$someServiceMock->expects($matcher)
40+
->method('run')
41+
->willReturnCallback(function () use ($matcher) {
42+
if ($matcher->numberOfInvocations() === 1) {
43+
return 'first';
44+
}
45+
throw new \PHPUnit\Framework\Exception(sprintf('Method should not be called for the %dth time', $matcher->numberOfInvocations()));
46+
});
47+
}
48+
}
49+
50+
?>
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\WillReturnCallbackFallbackToThrowRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class WillReturnCallbackFallbackToThrowRectorTest 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+
}
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\WillReturnCallbackFallbackToThrowRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->rule(WillReturnCallbackFallbackToThrowRector::class);
10+
};

rules/CodeQuality/Rector/Class_/TestWithToDataProviderRector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ private function refactorClassMethod(Class_ $class, ClassMethod $classMethod): v
152152
$arrayItemsSingleLine[] = new ArrayItem($this->createArrayItem($values[0]));
153153
}
154154

155-
//cleanup
155+
// cleanup
156156
if ($this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $testWithPhpDocTagNode)) {
157157
$this->hasChanged = true;
158158
}

0 commit comments

Comments
 (0)