10
10
use PHPStan \Rules \RuleErrorBuilder ;
11
11
use PHPUnit \Framework \TestCase ;
12
12
use function sprintf ;
13
- use function str_ends_with ;
13
+ use function strlen ;
14
+ use function substr_compare ;
14
15
15
16
/**
16
17
* @implements Rule<Node\Stmt\Class_>
@@ -36,8 +37,7 @@ public function processNode(Node $node, Scope $scope): array
36
37
return [];
37
38
}
38
39
39
- $ className = $ node ->namespacedName ->name ;
40
- $ class = $ this ->reflectionProvider ->getClass ($ className );
40
+ $ class = $ this ->reflectionProvider ->getClass ($ node ->namespacedName ->toString ());
41
41
42
42
if (!$ class ->isSubclassOf (TestCase::class)) {
43
43
return [];
@@ -48,7 +48,7 @@ public function processNode(Node $node, Scope $scope): array
48
48
if ($ class ->isAbstract ()) {
49
49
$ this ->requireSuffix (
50
50
$ errors ,
51
- $ className ,
51
+ $ class -> getName () ,
52
52
'TestCase ' ,
53
53
'Abstract test case class, \'%s \', should be named ending in \'%s \'. ' ,
54
54
);
@@ -58,15 +58,15 @@ public function processNode(Node $node, Scope $scope): array
58
58
59
59
$ this ->requireSuffix (
60
60
$ errors ,
61
- $ className ,
61
+ $ class -> getName () ,
62
62
'Test ' ,
63
63
'Concrete test class, \'%s \', should be named ending in \'%s \'. ' ,
64
64
);
65
65
66
66
if (!$ class ->isFinal ()) {
67
67
$ errors [] = RuleErrorBuilder::message (sprintf (
68
68
'Concrete test class, \'%s \', should be declared final. ' ,
69
- $ className ,
69
+ $ class -> getName () ,
70
70
))->identifier ('phpunit.naming ' )->build ();
71
71
}
72
72
@@ -75,19 +75,37 @@ public function processNode(Node $node, Scope $scope): array
75
75
76
76
/**
77
77
* @param list<IdentifierRuleError> $errors
78
+ * @param class-string $className
79
+ * @param non-empty-string $suffix
78
80
*/
79
81
private function requireSuffix (array &$ errors , string $ className , string $ suffix , string $ messageFormat ): void
80
82
{
81
- if (str_ends_with ($ className , $ suffix )) {
83
+ if ($ this -> hasSuffix ($ className , $ suffix )) {
82
84
return ;
83
85
}
84
86
85
- // @todo Case sensitivity??
86
87
$ errors [] = RuleErrorBuilder::message (sprintf (
87
88
$ messageFormat ,
88
89
$ className ,
89
90
$ suffix ,
90
91
))->identifier ('phpunit.naming ' )->build ();
91
92
}
92
93
94
+ /**
95
+ * Checks if class name has the given suffix.
96
+ *
97
+ * Comparison is case insensitive.
98
+ *
99
+ * @param class-string $className
100
+ * @param non-empty-string $suffix
101
+ */
102
+ private function hasSuffix (string $ className , string $ suffix ): bool
103
+ {
104
+ $ classNameLen = strlen ($ className );
105
+ $ suffixLen = strlen ($ suffix );
106
+
107
+ return $ suffixLen < $ classNameLen
108
+ && substr_compare ($ className , $ suffix , -$ suffixLen , $ suffixLen , true ) === 0 ;
109
+ }
110
+
93
111
}
0 commit comments