Skip to content

Commit 4a5c2dc

Browse files
committed
Updates rector/rector dependency
- Updates rector/rector dependency to the latest patch version. - Improves type safety and robustness in tests. - Fixes potential issues in tests by adding type checks and null assertions.
1 parent 51b8f33 commit 4a5c2dc

File tree

8 files changed

+103
-35
lines changed

8 files changed

+103
-35
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"symfony/validator": "^8.0",
2626
"psr/cache": "^3.0",
2727
"psr/simple-cache": "^3.0",
28-
"rector/rector": "^2.2"
28+
"rector/rector": "^2.2.11"
2929
},
3030
"autoload": {
3131
"psr-4": {

tests/Unit/Bridge/Rector/RegexOptimizationRectorTest.php

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace RegexParser\Tests\Unit\Bridge\Rector;
1515

1616
use PhpParser\Node\Expr\FuncCall;
17+
use PhpParser\Node\Scalar\String_;
1718
use PhpParser\Node\Stmt\ClassConst;
1819
use PhpParser\ParserFactory;
1920
use PHPUnit\Framework\TestCase;
@@ -30,15 +31,20 @@ public function test_refactors_configured_function_call(): void
3031
$this->initializeDependencies($rector);
3132

3233
$parser = new ParserFactory()->createForNewestSupportedVersion();
33-
$stmts = $parser->parse('<?php my_func("/[a-zA-Z0-9_]+/", $s);');
34+
$stmts = array_values($parser->parse('<?php my_func("/[a-zA-Z0-9_]+/", $s);') ?? []);
3435
$funcCall = $this->findNode($stmts, FuncCall::class);
3536

36-
$this->assertInstanceOf(FuncCall::class, $funcCall);
37+
if (!$funcCall instanceof FuncCall) {
38+
self::fail('FuncCall not found');
39+
}
3740
$modified = $rector->refactor($funcCall);
3841

3942
$this->assertNotInstanceOf(\PhpParser\Node::class, $modified);
40-
$this->assertInstanceOf(\PhpParser\Node\Expr\FuncCall::class, $funcCall);
41-
$this->assertSame('/[a-zA-Z0-9_]+/', $funcCall->getArgs()[0]->value->value);
43+
$patternArg = $funcCall->getArgs()[0]->value;
44+
if (!$patternArg instanceof String_) {
45+
self::fail('Pattern argument not string literal');
46+
}
47+
$this->assertSame('/[a-zA-Z0-9_]+/', $patternArg->value);
4248
}
4349

4450
public function test_refactors_configured_class_constant(): void
@@ -48,13 +54,16 @@ public function test_refactors_configured_class_constant(): void
4854
$this->initializeDependencies($rector);
4955

5056
$parser = new ParserFactory()->createForNewestSupportedVersion();
51-
$stmts = $parser->parse('<?php class A { public const MY_REGEX = "/[a-zA-Z0-9_]+/"; }');
57+
$stmts = array_values($parser->parse('<?php class A { public const MY_REGEX = "/[a-zA-Z0-9_]+/"; }') ?? []);
5258
$const = $this->findNode($stmts, ClassConst::class);
5359

54-
$this->assertInstanceOf(ClassConst::class, $const);
60+
if (!$const instanceof ClassConst) {
61+
self::fail('ClassConst not found');
62+
}
5563
$modified = $rector->refactor($const);
5664

5765
$this->assertNotInstanceOf(\PhpParser\Node::class, $modified);
66+
$this->assertInstanceOf(String_::class, $const->consts[0]->value);
5867
$this->assertSame('/[a-zA-Z0-9_]+/', $const->consts[0]->value->value);
5968
}
6069

@@ -65,6 +74,22 @@ public function test_refactors_configured_class_constant(): void
6574
*
6675
* @return T|null
6776
*/
77+
/**
78+
* @template T of \PhpParser\Node
79+
*
80+
* @param array<int, \PhpParser\Node\Stmt> $stmts
81+
* @param class-string<T> $class
82+
*
83+
* @return T|null
84+
*/
85+
/**
86+
* @template T of \PhpParser\Node
87+
*
88+
* @param array<int, \PhpParser\Node\Stmt> $stmts
89+
* @param class-string<T> $class
90+
*
91+
* @return T|null
92+
*/
6893
private function findNode(array $stmts, string $class): ?\PhpParser\Node
6994
{
7095
foreach ($stmts as $stmt) {
@@ -80,7 +105,7 @@ private function findNode(array $stmts, string $class): ?\PhpParser\Node
80105
return $node;
81106
}
82107
}
83-
} elseif ($child instanceof $class) {
108+
} elseif ($child instanceof \PhpParser\Node && $child instanceof $class) {
84109
return $child;
85110
}
86111
}

tests/Unit/Bridge/Symfony/Analyzer/RouteRequirementAnalyzerTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
namespace RegexParser\Tests\Unit\Bridge\Symfony\Analyzer;
1515

1616
use PHPUnit\Framework\TestCase;
17-
use RegexParser\Bridge\Symfony\Analyzer\AnalysisIssue;
1817
use RegexParser\Bridge\Symfony\Analyzer\RouteRequirementAnalyzer;
1918
use Symfony\Component\Routing\Route;
2019
use Symfony\Component\Routing\RouteCollection;
@@ -35,7 +34,7 @@ public function test_analyze_returns_issues_for_invalid_and_complex_patterns():
3534
$issues = $analyzer->analyze($routes);
3635

3736
$this->assertCount(2, $issues);
38-
$this->assertTrue($issues[0] instanceof AnalysisIssue && $issues[0]->isError);
37+
$this->assertTrue($issues[0]->isError);
3938
$this->assertFalse($issues[1]->isError); // warning threshold exceeded
4039
}
4140

tests/Unit/Bridge/Symfony/Analyzer/ValidatorRegexAnalyzerTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
namespace RegexParser\Tests\Unit\Bridge\Symfony\Analyzer;
1515

1616
use PHPUnit\Framework\TestCase;
17-
use RegexParser\Bridge\Symfony\Analyzer\AnalysisIssue;
1817
use RegexParser\Bridge\Symfony\Analyzer\ValidatorRegexAnalyzer;
1918
use Symfony\Component\Validator\Constraints\Regex as SymfonyRegex;
2019
use Symfony\Component\Validator\ConstraintViolationListInterface;
@@ -42,6 +41,9 @@ public function loadClassMetadata(ClassMetadata $metadata): bool
4241
return true;
4342
}
4443

44+
/**
45+
* @return array<int, class-string<DummyValidated>>
46+
*/
4547
public function getMappedClasses(): array
4648
{
4749
return [DummyValidated::class];
@@ -52,7 +54,7 @@ public function getMappedClasses(): array
5254
$issues = $analyzer->analyze($validator, $loader);
5355

5456
$this->assertCount(3, $issues);
55-
$this->assertTrue($issues[0] instanceof AnalysisIssue && $issues[0]->isError);
57+
$this->assertTrue($issues[0]->isError);
5658
$this->assertFalse($issues[1]->isError);
5759
$this->assertFalse($issues[2]->isError);
5860
}
@@ -80,6 +82,9 @@ public function loadClassMetadata(ClassMetadata $metadata): bool
8082
return true;
8183
}
8284

85+
/**
86+
* @return array<int, class-string<DummyValidated>>
87+
*/
8388
public function getMappedClasses(): array
8489
{
8590
return [DummyValidated::class];

tests/Unit/Bridge/Symfony/Command/RegexParserValidateCommandTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,17 @@ public function getContext(): \Symfony\Component\Routing\RequestContext
6464
return new \Symfony\Component\Routing\RequestContext();
6565
}
6666

67+
/**
68+
* @param array<string, mixed> $parameters
69+
*/
6770
public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string
6871
{
6972
return '';
7073
}
7174

75+
/**
76+
* @return array<string, mixed>
77+
*/
7278
public function match(string $pathinfo): array
7379
{
7480
return [];

tests/Unit/Bridge/Symfony/ConfigurationTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ public function test_default_configuration(): void
2525
$processor = new Processor();
2626
$configuration = new Configuration(false);
2727

28+
/**
29+
* @var array{
30+
* enabled: bool,
31+
* max_pattern_length: int,
32+
* cache: string|null,
33+
* analysis: array{
34+
* warning_threshold: int,
35+
* redos_threshold: int,
36+
* ignore_patterns: array<int, string>
37+
* }
38+
* } $config
39+
*/
2840
$config = $processor->processConfiguration($configuration, []);
2941

3042
$this->assertFalse($config['enabled']);
@@ -40,6 +52,18 @@ public function test_custom_configuration(): void
4052
$processor = new Processor();
4153
$configuration = new Configuration(true);
4254

55+
/**
56+
* @var array{
57+
* enabled: bool,
58+
* max_pattern_length: int,
59+
* cache: string|null,
60+
* analysis: array{
61+
* warning_threshold: int,
62+
* redos_threshold: int,
63+
* ignore_patterns: array<int, string>
64+
* }
65+
* } $config
66+
*/
4367
$config = $processor->processConfiguration($configuration, [[
4468
'enabled' => true,
4569
'max_pattern_length' => 10,
@@ -51,6 +75,19 @@ public function test_custom_configuration(): void
5175
],
5276
]]);
5377

78+
/*
79+
* @var array{
80+
* enabled: bool,
81+
* max_pattern_length: int,
82+
* cache: string|null,
83+
* analysis: array{
84+
* warning_threshold: int,
85+
* redos_threshold: int,
86+
* ignore_patterns: array<int, string>
87+
* }
88+
* } $config
89+
*/
90+
5491
$this->assertTrue($config['enabled']);
5592
$this->assertSame(10, $config['max_pattern_length']);
5693
$this->assertSame('/tmp/cache', $config['cache']);

tests/Unit/Cache/FilesystemCacheTest.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,19 @@ protected function tearDown(): void
3434
);
3535

3636
foreach ($iterator as $fileInfo) {
37+
if (!$fileInfo instanceof \SplFileInfo) {
38+
continue;
39+
}
40+
41+
$path = $fileInfo->getPathname();
42+
if (!\is_string($path)) {
43+
continue;
44+
}
45+
3746
if ($fileInfo->isDir()) {
38-
@rmdir($fileInfo->getPathname());
47+
@rmdir($path);
3948
} else {
40-
@unlink($fileInfo->getPathname());
49+
@unlink($path);
4150
}
4251
}
4352

tests/Unit/Cache/PsrCacheAdapterTest.php

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Psr\Cache\CacheItemInterface;
1818
use Psr\Cache\CacheItemPoolInterface;
1919
use RegexParser\Cache\PsrCacheAdapter;
20+
use RegexParser\Node\LiteralNode;
2021
use RegexParser\Node\RegexNode;
2122

2223
final class PsrCacheAdapterTest extends TestCase
@@ -47,15 +48,15 @@ public function test_write_and_load_decoded_payload(): void
4748
$pool = new InMemoryPool();
4849
$cache = new PsrCacheAdapter($pool);
4950

50-
$payload = "<?php return new \\RegexParser\\Node\\RegexNode(new \\RegexParser\\Tests\\Unit\\Cache\\DummyNode(), '', '/', 0, 0);";
51+
$payload = "<?php return new \\RegexParser\\Node\\RegexNode(new \\RegexParser\\Node\\LiteralNode('', 0, 0), '', '/', 0, 0);";
5152

5253
$key = $cache->generateKey('foo');
5354
$cache->write($key, $payload);
5455

5556
$loaded = $cache->load($key);
5657

5758
$this->assertInstanceOf(RegexNode::class, $loaded);
58-
$this->assertInstanceOf(DummyNode::class, $loaded->pattern);
59+
$this->assertInstanceOf(LiteralNode::class, $loaded->pattern);
5960
}
6061

6162
public function test_write_falls_back_to_raw_payload_on_error(): void
@@ -88,24 +89,6 @@ public function test_clear(): void
8889
}
8990
}
9091

91-
final class DummyNode implements \RegexParser\Node\NodeInterface
92-
{
93-
public function accept(\RegexParser\NodeVisitor\NodeVisitorInterface $visitor): mixed
94-
{
95-
return null;
96-
}
97-
98-
public function getStartPosition(): int
99-
{
100-
return 0;
101-
}
102-
103-
public function getEndPosition(): int
104-
{
105-
return 0;
106-
}
107-
}
108-
10992
final class InMemoryPool implements CacheItemPoolInterface
11093
{
11194
/**
@@ -118,10 +101,14 @@ public function getItem(string $key): CacheItemInterface
118101
return $this->items[$key] ??= new InMemoryItem($key);
119102
}
120103

104+
/**
105+
* @return iterable<string, CacheItemInterface>
106+
*/
121107
public function getItems(array $keys = []): iterable
122108
{
123109
foreach ($keys as $key) {
124-
yield $this->getItem($key);
110+
$key = (string) $key;
111+
yield $key => $this->getItem($key);
125112
}
126113
}
127114

0 commit comments

Comments
 (0)