Skip to content

Commit 21c7c03

Browse files
authored
Add ReplaceFakerInstanceWithHelperRector (#77)
Add ReplaceFakerInstanceWithHelperRector
1 parent c97cbf7 commit 21c7c03

File tree

9 files changed

+245
-1
lines changed

9 files changed

+245
-1
lines changed

config/sets/laravel90.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Rector\Renaming\ValueObject\MethodCallRename;
1111
use Rector\Visibility\Rector\ClassMethod\ChangeMethodVisibilityRector;
1212
use Rector\Visibility\ValueObject\ChangeMethodVisibility;
13+
use RectorLaravel\Rector\PropertyFetch\ReplaceFakerInstanceWithHelperRector;
1314

1415
# see https://laravel.com/docs/9.x/upgrade
1516
return static function (RectorConfig $rectorConfig): void {
@@ -77,6 +78,9 @@
7778
),
7879
]);
7980

81+
// https://github.com/laravel/framework/commit/7746337149a7ffd6b4a862d9bd54593cf3520708
82+
$rectorConfig->rule(ReplaceFakerInstanceWithHelperRector::class);
83+
8084
$rectorConfig
8185
->ruleWithConfiguration(RenameMethodRector::class, [
8286
// https://github.com/laravel/framework/commit/9b4f011fb95c70444812f61d46c8e21fb5b66dd9

docs/rector_rules_overview.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 26 Rules Overview
1+
# 27 Rules Overview
22

33
## AddArgumentDefaultValueRector
44

@@ -525,6 +525,29 @@ It will removes the dump data just like dd or dump functions from the code.`
525525

526526
<br>
527527

528+
## ReplaceFakerInstanceWithHelperRector
529+
530+
Replace `$this->faker` with the `fake()` helper function in Factories
531+
532+
- class: [`RectorLaravel\Rector\PropertyFetch\ReplaceFakerInstanceWithHelperRector`](../src/Rector/PropertyFetch/ReplaceFakerInstanceWithHelperRector.php)
533+
534+
```diff
535+
class UserFactory extends Factory
536+
{
537+
public function definition()
538+
{
539+
return [
540+
- 'name' => $this->faker->name,
541+
- 'email' => $this->faker->unique()->safeEmail,
542+
+ 'name' => fake()->name,
543+
+ 'email' => fake()->unique()->safeEmail,
544+
];
545+
}
546+
}
547+
```
548+
549+
<br>
550+
528551
## RequestStaticValidateToInjectRector
529552

530553
Change static `validate()` method to `$request->validate()`
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RectorLaravel\Rector\PropertyFetch;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\MethodCall;
9+
use PhpParser\Node\Expr\PropertyFetch;
10+
use PhpParser\Node\Stmt\Class_;
11+
use PhpParser\Node\Stmt\ClassLike;
12+
use PHPStan\Type\ObjectType;
13+
use Rector\Core\Rector\AbstractRector;
14+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
15+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
16+
17+
/**
18+
* @see \RectorLaravel\Tests\Rector\PropertyFetch\ReplaceFakerInstanceWithHelperRector\ReplaceFakerInstanceWithHelperRectorTest
19+
*/
20+
final class ReplaceFakerInstanceWithHelperRector extends AbstractRector
21+
{
22+
public function getRuleDefinition(): RuleDefinition
23+
{
24+
return new RuleDefinition(
25+
'Replace $this->faker with the fake() helper function in Factories',
26+
[
27+
new CodeSample(
28+
<<<'CODE_SAMPLE'
29+
class UserFactory extends Factory
30+
{
31+
public function definition()
32+
{
33+
return [
34+
'name' => $this->faker->name,
35+
'email' => $this->faker->unique()->safeEmail,
36+
];
37+
}
38+
}
39+
CODE_SAMPLE
40+
,
41+
<<<'CODE_SAMPLE'
42+
class UserFactory extends Factory
43+
{
44+
public function definition()
45+
{
46+
return [
47+
'name' => fake()->name,
48+
'email' => fake()->unique()->safeEmail,
49+
];
50+
}
51+
}
52+
CODE_SAMPLE
53+
),
54+
]
55+
);
56+
}
57+
58+
/**
59+
* @return array<class-string<Node>>
60+
*/
61+
public function getNodeTypes(): array
62+
{
63+
return [PropertyFetch::class];
64+
}
65+
66+
/**
67+
* @param PropertyFetch $node
68+
*/
69+
public function refactor(Node $node): ?Node
70+
{
71+
if ($this->shouldSkipNode($node)) {
72+
return null;
73+
}
74+
75+
return $this->nodeFactory->createFuncCall('fake');
76+
}
77+
78+
private function shouldSkipNode(PropertyFetch $propertyFetch): bool
79+
{
80+
if (! $this->isName($propertyFetch->var, 'this')) {
81+
return true;
82+
}
83+
84+
if (! $this->isName($propertyFetch->name, 'faker')) {
85+
return true;
86+
}
87+
88+
// The randomEnum() method is a special case where the faker instance is used
89+
// see https://github.com/spatie/laravel-enum#faker-provider
90+
$parent = $propertyFetch->getAttribute('parent');
91+
92+
if ($parent instanceof MethodCall && $this->isName($parent->name, 'randomEnum')) {
93+
return true;
94+
}
95+
96+
$classLike = $this->betterNodeFinder->findParentType($propertyFetch, ClassLike::class);
97+
98+
if (! $classLike instanceof ClassLike) {
99+
return true;
100+
}
101+
102+
if ($classLike instanceof Class_) {
103+
return ! $this->isObjectType($classLike, new ObjectType('Illuminate\Database\Eloquent\Factories\Factory'));
104+
}
105+
106+
return false;
107+
}
108+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
use Illuminate\Database\Eloquent\Factories\Factory;
3+
4+
class UserFactory extends Factory
5+
{
6+
public function definition()
7+
{
8+
return [
9+
'name' => $this->faker->name,
10+
'email' => $this->faker->unique()->safeEmail,
11+
];
12+
}
13+
}
14+
?>
15+
-----
16+
<?php
17+
use Illuminate\Database\Eloquent\Factories\Factory;
18+
19+
class UserFactory extends Factory
20+
{
21+
public function definition()
22+
{
23+
return [
24+
'name' => fake()->name,
25+
'email' => fake()->unique()->safeEmail,
26+
];
27+
}
28+
}
29+
?>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
use Illuminate\Database\Eloquent\Factories\Factory;
4+
5+
class UserFactory extends Factory
6+
{
7+
public function definition()
8+
{
9+
return [
10+
'name' => fake()->name,
11+
'email' => fake()->unique()->safeEmail,
12+
'test' => $this->test,
13+
];
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
class SomeFactory
4+
{
5+
public function definition()
6+
{
7+
return [
8+
'name' => $this->faker->name,
9+
'email' => $this->faker->unique()->safeEmail,
10+
];
11+
}
12+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
use Illuminate\Database\Eloquent\Factories\Factory;
4+
5+
class TestFactory extends Factory
6+
{
7+
public function definition()
8+
{
9+
return [
10+
'name' => $this->faker->randomEnum(SomeEnum::class),
11+
];
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RectorLaravel\Tests\Rector\PropertyFetch\ReplaceFakerInstanceWithHelperRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class ReplaceFakerInstanceWithHelperRectorTest extends AbstractRectorTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
}
18+
19+
public 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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use RectorLaravel\Rector\PropertyFetch\ReplaceFakerInstanceWithHelperRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->import(__DIR__ . '/../../../../../config/config.php');
10+
11+
$rectorConfig->rule(ReplaceFakerInstanceWithHelperRector::class);
12+
};

0 commit comments

Comments
 (0)