Skip to content

Commit 3c78b0a

Browse files
peterfoxdriftingly
andauthored
AssertStatus to Dedicated Assert method (#71)
* Working Status to Method Rector Rule * converts constants as well * Improved Code Sample * Adds additional test --------- Co-authored-by: Anthony Clark <[email protected]>
1 parent 731050b commit 3c78b0a

12 files changed

+706
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RectorLaravel\Rector\MethodCall;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\MethodCall;
9+
use PHPStan\Type\ObjectType;
10+
use Rector\Core\Rector\AbstractRector;
11+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
12+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
13+
14+
/**
15+
* @see \RectorLaravel\Tests\Rector\MethodCall\RedirectBackToBackHelperRector\RedirectBackToBackHelperRectorTest
16+
*/
17+
18+
final class AssertStatusToAssertMethodRector extends AbstractRector
19+
{
20+
public function getRuleDefinition(): RuleDefinition
21+
{
22+
return new RuleDefinition(
23+
'Replace `(new \Illuminate\Testing\TestResponse)->assertStatus(200)` with `(new \Illuminate\Testing\TestResponse)->assertOk()`',
24+
[
25+
new CodeSample(
26+
<<<'CODE_SAMPLE'
27+
class ExampleTest extends \Illuminate\Foundation\Testing\TestCase
28+
{
29+
public function testOk()
30+
{
31+
$this->get('/')->assertStatus(200);
32+
$this->get('/')->assertStatus(\Illuminate\Http\Response::HTTP_OK);
33+
$this->get('/')->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_OK);
34+
}
35+
36+
public function testNoContent()
37+
{
38+
$this->get('/')->assertStatus(204);
39+
$this->get('/')->assertStatus(\Illuminate\Http\Response::HTTP_NO_CONTENT);
40+
$this->get('/')->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_NO_CONTENT);
41+
}
42+
43+
public function testUnauthorized()
44+
{
45+
$this->get('/')->assertStatus(401);
46+
$this->get('/')->assertStatus(\Illuminate\Http\Response::HTTP_UNAUTHORIZED);
47+
$this->get('/')->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_UNAUTHORIZED);
48+
}
49+
50+
public function testForbidden()
51+
{
52+
$this->get('/')->assertStatus(403);
53+
$this->get('/')->assertStatus(\Illuminate\Http\Response::HTTP_FORBIDDEN);
54+
$this->get('/')->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_FORBIDDEN);
55+
}
56+
57+
public function testNotFound()
58+
{
59+
$this->get('/')->assertStatus(404);
60+
$this->get('/')->assertStatus(\Illuminate\Http\Response::HTTP_NOT_FOUND);
61+
$this->get('/')->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_NOT_FOUND);
62+
}
63+
64+
public function testUnprocessableEntity()
65+
{
66+
$this->get('/')->assertStatus(422);
67+
$this->get('/')->assertStatus(\Illuminate\Http\Response::HTTP_UNPROCESSABLE_ENTITY);
68+
$this->get('/')->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_UNPROCESSABLE_ENTITY);
69+
}
70+
}
71+
CODE_SAMPLE
72+
,
73+
<<<'CODE_SAMPLE'
74+
class ExampleTest extends \Illuminate\Foundation\Testing\TestCase
75+
{
76+
public function testOk()
77+
{
78+
$this->get('/')->assertOk();
79+
$this->get('/')->assertOk();
80+
$this->get('/')->assertOk();
81+
}
82+
83+
public function testNoContent()
84+
{
85+
$this->get('/')->assertNoContent();
86+
$this->get('/')->assertNoContent();
87+
$this->get('/')->assertNoContent();
88+
}
89+
90+
public function testUnauthorized()
91+
{
92+
$this->get('/')->assertUnauthorized();
93+
$this->get('/')->assertUnauthorized();
94+
$this->get('/')->assertUnauthorized();
95+
}
96+
97+
public function testForbidden()
98+
{
99+
$this->get('/')->assertForbidden();
100+
$this->get('/')->assertForbidden();
101+
$this->get('/')->assertForbidden();
102+
}
103+
104+
public function testNotFound()
105+
{
106+
$this->get('/')->assertNotFound();
107+
$this->get('/')->assertNotFound();
108+
$this->get('/')->assertNotFound();
109+
}
110+
111+
public function testUnprocessableEntity()
112+
{
113+
$this->get('/')->assertUnprocessable();
114+
$this->get('/')->assertUnprocessable();
115+
$this->get('/')->assertUnprocessable();
116+
}
117+
}
118+
CODE_SAMPLE
119+
),
120+
]
121+
);
122+
}
123+
124+
/**
125+
* @return array<class-string<Node>>
126+
*/
127+
public function getNodeTypes(): array
128+
{
129+
return [MethodCall::class];
130+
}
131+
132+
/**
133+
* @param MethodCall $node
134+
*/
135+
public function refactor(Node $node): ?Node
136+
{
137+
return $this->updateAssertStatusCall($node);
138+
}
139+
140+
private function updateAssertStatusCall(MethodCall $methodCall): ?MethodCall
141+
{
142+
if (! $this->isName($methodCall->name, 'assertStatus')) {
143+
return null;
144+
}
145+
146+
if (! $this->isObjectType($methodCall->var, new ObjectType('Illuminate\Testing\TestResponse'))) {
147+
return null;
148+
}
149+
150+
if (count($methodCall->getArgs()) <> 1) {
151+
return null;
152+
}
153+
154+
$arg = $methodCall->getArgs()[0];
155+
$argValue = $arg->value;
156+
157+
if (! $argValue instanceof Node\Scalar\LNumber && ! $argValue instanceof Node\Expr\ClassConstFetch) {
158+
return null;
159+
}
160+
161+
if ($argValue instanceof Node\Scalar\LNumber) {
162+
$replacementMethod = match ($argValue->value) {
163+
200 => 'assertOk',
164+
204 => 'assertNoContent',
165+
401 => 'assertUnauthorized',
166+
403 => 'assertForbidden',
167+
404 => 'assertNotFound',
168+
422 => 'assertUnprocessable',
169+
default => null
170+
};
171+
} else {
172+
if (! in_array($this->getName($argValue->class), [
173+
'Illuminate\Http\Response',
174+
'Symfony\Component\HttpFoundation\Response'
175+
], true)) {
176+
return null;
177+
}
178+
179+
$replacementMethod = match ($this->getName($argValue->name)) {
180+
'HTTP_OK' => 'assertOk',
181+
'HTTP_NO_CONTENT' => 'assertNoContent',
182+
'HTTP_UNAUTHORIZED' => 'assertUnauthorized',
183+
'HTTP_FORBIDDEN' => 'assertForbidden',
184+
'HTTP_NOT_FOUND' => 'assertNotFound',
185+
'HTTP_UNPROCESSABLE_ENTITY' => 'assertUnprocessable',
186+
default => null
187+
};
188+
}
189+
190+
if ($replacementMethod === null) {
191+
return null;
192+
}
193+
194+
$methodCall->name = new Node\Identifier($replacementMethod);
195+
$methodCall->args = [];
196+
197+
return $methodCall;
198+
}
199+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RectorLaravel\Tests\Rector\MethodCall\AssertStatusToAssertMethodRector;
6+
7+
use Iterator;
8+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
9+
10+
final class AssertStatusToAssertMethodTest extends AbstractRectorTestCase
11+
{
12+
/**
13+
* @dataProvider provideData()
14+
*/
15+
public function test(string $filePath): void
16+
{
17+
$this->doTestFile($filePath);
18+
}
19+
20+
public function provideData(): Iterator
21+
{
22+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
23+
}
24+
25+
public function provideConfigFilePath(): string
26+
{
27+
return __DIR__ . '/config/configured_rule.php';
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\MethodCall\AssertStatusToAssertMethodRector\Fixture;
4+
5+
class FixtureWithIlluminateTest
6+
{
7+
public function testOk(\Illuminate\Testing\TestResponse $response)
8+
{
9+
$response->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_OK);
10+
}
11+
12+
public function testNoContent(\Illuminate\Testing\TestResponse $response)
13+
{
14+
$response->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_NO_CONTENT);
15+
}
16+
17+
public function testForbidden(\Illuminate\Testing\TestResponse $response)
18+
{
19+
$response->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_FORBIDDEN);
20+
}
21+
22+
public function testNotFound(\Illuminate\Testing\TestResponse $response)
23+
{
24+
$response->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_NOT_FOUND);
25+
}
26+
27+
public function testUnauthorized(\Illuminate\Testing\TestResponse $response)
28+
{
29+
$response->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_UNAUTHORIZED);
30+
}
31+
32+
public function testUnprocessableEntity(\Illuminate\Testing\TestResponse $response)
33+
{
34+
$response->assertStatus(\Symfony\Component\HttpFoundation\Response::HTTP_UNPROCESSABLE_ENTITY);
35+
}
36+
}
37+
38+
?>
39+
-----
40+
<?php
41+
42+
namespace RectorLaravel\Tests\Rector\MethodCall\AssertStatusToAssertMethodRector\Fixture;
43+
44+
class FixtureWithIlluminateTest
45+
{
46+
public function testOk(\Illuminate\Testing\TestResponse $response)
47+
{
48+
$response->assertOk();
49+
}
50+
51+
public function testNoContent(\Illuminate\Testing\TestResponse $response)
52+
{
53+
$response->assertNoContent();
54+
}
55+
56+
public function testForbidden(\Illuminate\Testing\TestResponse $response)
57+
{
58+
$response->assertForbidden();
59+
}
60+
61+
public function testNotFound(\Illuminate\Testing\TestResponse $response)
62+
{
63+
$response->assertNotFound();
64+
}
65+
66+
public function testUnauthorized(\Illuminate\Testing\TestResponse $response)
67+
{
68+
$response->assertUnauthorized();
69+
}
70+
71+
public function testUnprocessableEntity(\Illuminate\Testing\TestResponse $response)
72+
{
73+
$response->assertUnprocessable();
74+
}
75+
}
76+
77+
?>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\MethodCall\AssertStatusToAssertMethodRector\Fixture;
4+
5+
class FixtureTest
6+
{
7+
public function testOk(\Illuminate\Testing\TestResponse $response)
8+
{
9+
$response->assertStatus(200);
10+
}
11+
12+
public function testNoContent(\Illuminate\Testing\TestResponse $response)
13+
{
14+
$response->assertStatus(204);
15+
}
16+
17+
public function testForbidden(\Illuminate\Testing\TestResponse $response)
18+
{
19+
$response->assertStatus(403);
20+
}
21+
22+
public function testNotFound(\Illuminate\Testing\TestResponse $response)
23+
{
24+
$response->assertStatus(404);
25+
}
26+
27+
public function testUnauthorized(\Illuminate\Testing\TestResponse $response)
28+
{
29+
$response->assertStatus(401);
30+
}
31+
32+
public function testUnprocessableEntity(\Illuminate\Testing\TestResponse $response)
33+
{
34+
$response->assertStatus(422);
35+
}
36+
}
37+
38+
?>
39+
-----
40+
<?php
41+
42+
namespace RectorLaravel\Tests\Rector\MethodCall\AssertStatusToAssertMethodRector\Fixture;
43+
44+
class FixtureTest
45+
{
46+
public function testOk(\Illuminate\Testing\TestResponse $response)
47+
{
48+
$response->assertOk();
49+
}
50+
51+
public function testNoContent(\Illuminate\Testing\TestResponse $response)
52+
{
53+
$response->assertNoContent();
54+
}
55+
56+
public function testForbidden(\Illuminate\Testing\TestResponse $response)
57+
{
58+
$response->assertForbidden();
59+
}
60+
61+
public function testNotFound(\Illuminate\Testing\TestResponse $response)
62+
{
63+
$response->assertNotFound();
64+
}
65+
66+
public function testUnauthorized(\Illuminate\Testing\TestResponse $response)
67+
{
68+
$response->assertUnauthorized();
69+
}
70+
71+
public function testUnprocessableEntity(\Illuminate\Testing\TestResponse $response)
72+
{
73+
$response->assertUnprocessable();
74+
}
75+
}
76+
77+
?>

0 commit comments

Comments
 (0)