Skip to content

Commit 8d39c5b

Browse files
tamirohGeniJaho
andauthored
Add CarbonSetTestNowToTravelToRector rule (#240)
* Add `CarbonSetTestNowToTravelToRector` * Rename fixture * Add more fixtures * Add fixture * Add fixture * Add more tests * Update doc --------- Co-authored-by: Geni Jaho <jahogeni@gmail.com>
1 parent 1d57d99 commit 8d39c5b

9 files changed

+344
-1
lines changed

docs/rector_rules_overview.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 64 Rules Overview
1+
# 65 Rules Overview
22

33
## AbortIfRector
44

@@ -396,6 +396,28 @@ Replace magical call on `$this->app["something"]` to standalone type assign vari
396396

397397
<br>
398398

399+
## CarbonSetTestNowToTravelToRector
400+
401+
Use the `$this->travelTo()` method in Laravel's `TestCase` class instead of the `Carbon::setTestNow()` method.
402+
403+
- class: [`RectorLaravel\Rector\StaticCall\CarbonSetTestNowToTravelToRector`](../src/Rector/StaticCall/CarbonSetTestNowToTravelToRector.php)
404+
405+
```diff
406+
use Illuminate\Support\Carbon;
407+
use Illuminate\Foundation\Testing\TestCase;
408+
409+
class SomeTest extends TestCase
410+
{
411+
public function test()
412+
{
413+
- Carbon::setTestNow('2024-08-11');
414+
+ $this->travelTo('2024-08-11');
415+
}
416+
}
417+
```
418+
419+
<br>
420+
399421
## CashierStripeOptionsToStripeRector
400422

401423
Renames the Billable `stripeOptions()` to `stripe().`
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
namespace RectorLaravel\Rector\StaticCall;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Expr\MethodCall;
7+
use PhpParser\Node\Expr\StaticCall;
8+
use PhpParser\Node\Expr\Variable;
9+
use PHPStan\Analyser\Scope;
10+
use PHPStan\Type\ObjectType;
11+
use Rector\Rector\AbstractScopeAwareRector;
12+
use Symplify\RuleDocGenerator\Exception\PoorDocumentationException;
13+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
14+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
15+
16+
/**
17+
* @see \RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\CarbonSetTestNowToTravelToRectorTest
18+
*/
19+
final class CarbonSetTestNowToTravelToRector extends AbstractScopeAwareRector
20+
{
21+
/**
22+
* @throws PoorDocumentationException
23+
*/
24+
public function getRuleDefinition(): RuleDefinition
25+
{
26+
return new RuleDefinition(
27+
'Use the `$this->travelTo()` method in Laravel\'s `TestCase` class instead of the `Carbon::setTestNow()` method.',
28+
[
29+
new CodeSample(
30+
<<<'CODE_SAMPLE'
31+
use Illuminate\Support\Carbon;
32+
use Illuminate\Foundation\Testing\TestCase;
33+
34+
class SomeTest extends TestCase
35+
{
36+
public function test()
37+
{
38+
Carbon::setTestNow('2024-08-11');
39+
}
40+
}
41+
CODE_SAMPLE
42+
,
43+
<<<'CODE_SAMPLE'
44+
use Illuminate\Support\Carbon;
45+
use Illuminate\Foundation\Testing\TestCase;
46+
47+
class SomeTest extends TestCase
48+
{
49+
public function test()
50+
{
51+
$this->travelTo('2024-08-11');
52+
}
53+
}
54+
CODE_SAMPLE
55+
),
56+
],
57+
);
58+
}
59+
60+
/**
61+
* @return array<class-string<Node>>
62+
*/
63+
public function getNodeTypes(): array
64+
{
65+
return [StaticCall::class];
66+
}
67+
68+
public function refactorWithScope(Node $node, Scope $scope): ?MethodCall
69+
{
70+
if (! $node instanceof StaticCall) {
71+
return null;
72+
}
73+
74+
if (! $scope->isInClass()) {
75+
return null;
76+
}
77+
78+
if (! $scope->getClassReflection()->isSubclassOf('Illuminate\Foundation\Testing\TestCase')) {
79+
return null;
80+
}
81+
82+
if (! $this->isName($node->name, 'setTestNow')) {
83+
return null;
84+
}
85+
86+
if (! $this->isCarbon($node->class)) {
87+
return null;
88+
}
89+
90+
return $this->nodeFactory->createMethodCall(new Variable('this'), 'travelTo', $node->args);
91+
}
92+
93+
private function isCarbon(Node $node): bool
94+
{
95+
return $this->isObjectType($node, new ObjectType('Carbon\Carbon')) ||
96+
$this->isObjectType($node, new ObjectType('Carbon\CarbonImmutable')) ||
97+
$this->isObjectType($node, new ObjectType('Illuminate\Support\Carbon'));
98+
}
99+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Exception\ShouldNotHappenException;
10+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
11+
12+
final class CarbonSetTestNowToTravelToRectorTest extends AbstractRectorTestCase
13+
{
14+
public static function provideData(): Iterator
15+
{
16+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
17+
}
18+
19+
/**
20+
* @test
21+
*
22+
* @throws ShouldNotHappenException
23+
*/
24+
#[DataProvider('provideData')]
25+
public function test(string $filePath): void
26+
{
27+
$this->doTestFile($filePath);
28+
}
29+
30+
public function provideConfigFilePath(): string
31+
{
32+
return __DIR__ . '/config/configured_rule.php';
33+
}
34+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
4+
5+
use Foo\TestCase;
6+
use Carbon\Carbon;
7+
8+
class SomeTest extends TestCase
9+
{
10+
public function test()
11+
{
12+
Carbon::setTestNow('2024-08-11');
13+
Carbon::setTestNow(Carbon::parse('2024-08-11'));
14+
}
15+
}
16+
17+
?>
18+
-----
19+
<?php
20+
21+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
22+
23+
use Foo\TestCase;
24+
use Carbon\Carbon;
25+
26+
class SomeTest extends TestCase
27+
{
28+
public function test()
29+
{
30+
Carbon::setTestNow('2024-08-11');
31+
Carbon::setTestNow(Carbon::parse('2024-08-11'));
32+
}
33+
}
34+
35+
?>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
4+
5+
use Illuminate\Foundation\Testing\TestCase;
6+
use Carbon\Carbon;
7+
8+
class SomeTest extends TestCase
9+
{
10+
public function test()
11+
{
12+
Carbon::setTestNow('2024-08-11');
13+
Carbon::setTestNow(Carbon::parse('2024-08-11'));
14+
}
15+
}
16+
17+
?>
18+
-----
19+
<?php
20+
21+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
22+
23+
use Illuminate\Foundation\Testing\TestCase;
24+
use Carbon\Carbon;
25+
26+
class SomeTest extends TestCase
27+
{
28+
public function test()
29+
{
30+
$this->travelTo('2024-08-11');
31+
$this->travelTo(Carbon::parse('2024-08-11'));
32+
}
33+
}
34+
35+
?>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
4+
5+
use Illuminate\Foundation\Testing\TestCase;
6+
use Carbon\CarbonImmutable;
7+
8+
class SomeTest extends TestCase
9+
{
10+
public function test()
11+
{
12+
CarbonImmutable::setTestNow('2024-08-11');
13+
CarbonImmutable::setTestNow(CarbonImmutable::parse('2024-08-11'));
14+
}
15+
}
16+
17+
?>
18+
-----
19+
<?php
20+
21+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
22+
23+
use Illuminate\Foundation\Testing\TestCase;
24+
use Carbon\CarbonImmutable;
25+
26+
class SomeTest extends TestCase
27+
{
28+
public function test()
29+
{
30+
$this->travelTo('2024-08-11');
31+
$this->travelTo(CarbonImmutable::parse('2024-08-11'));
32+
}
33+
}
34+
35+
?>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
4+
5+
use Illuminate\Foundation\Testing\TestCase;
6+
use Illuminate\Support\Carbon;
7+
8+
class SomeTest extends TestCase
9+
{
10+
public function test()
11+
{
12+
Carbon::setTestNow('2024-08-11');
13+
Carbon::setTestNow(Carbon::parse('2024-08-11'));
14+
}
15+
}
16+
17+
?>
18+
-----
19+
<?php
20+
21+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
22+
23+
use Illuminate\Foundation\Testing\TestCase;
24+
use Illuminate\Support\Carbon;
25+
26+
class SomeTest extends TestCase
27+
{
28+
public function test()
29+
{
30+
$this->travelTo('2024-08-11');
31+
$this->travelTo(Carbon::parse('2024-08-11'));
32+
}
33+
}
34+
35+
?>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
4+
5+
use Carbon\Carbon;
6+
use Illuminate\Foundation\Testing\TestCase;
7+
use Foo\Bar;
8+
9+
class SomeTest extends TestCase
10+
{
11+
public function test()
12+
{
13+
Bar::setTestNow('2024-08-11');
14+
Bar::setTestNow(Carbon::parse('2024-08-11'));
15+
}
16+
}
17+
18+
?>
19+
-----
20+
<?php
21+
22+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonSetTestNowToTravelToRector\Fixture;
23+
24+
use Carbon\Carbon;
25+
use Illuminate\Foundation\Testing\TestCase;
26+
use Foo\Bar;
27+
28+
class SomeTest extends TestCase
29+
{
30+
public function test()
31+
{
32+
Bar::setTestNow('2024-08-11');
33+
Bar::setTestNow(Carbon::parse('2024-08-11'));
34+
}
35+
}
36+
37+
?>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use RectorLaravel\Rector\StaticCall\CarbonSetTestNowToTravelToRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->import(__DIR__ . '/../../../../../config/config.php');
10+
$rectorConfig->rule(CarbonSetTestNowToTravelToRector::class);
11+
};

0 commit comments

Comments
 (0)