22
33namespace PHPStan \Rules \PHPUnit ;
44
5+ use PHPStan \Analyser \Scope ;
56use PHPStan \Parser \Parser ;
7+ use PHPStan \PhpDoc \ResolvedPhpDocBlock ;
68use PHPStan \Reflection \ClassReflection ;
79use PHPStan \Reflection \ReflectionProvider ;
810use PHPStan \Type \FileTypeMapper ;
@@ -33,18 +35,43 @@ public function __construct(
3335 /**
3436 * @return array<ReflectionMethod>
3537 */
36- public function getTestMethods (ClassReflection $ class ): array
38+ public function getTestMethods (ClassReflection $ classReflection , Scope $ scope ): array
3739 {
3840 $ testMethods = [];
39- foreach ($ class ->getNativeReflection ()->getMethods () as $ reflectionMethod ) {
41+ foreach ($ classReflection ->getNativeReflection ()->getMethods () as $ reflectionMethod ) {
42+ if (!$ reflectionMethod ->isPublic ()) {
43+ continue ;
44+ }
45+
4046 if (str_starts_with (strtolower ($ reflectionMethod ->getName ()), 'test ' )) {
4147 $ testMethods [] = $ reflectionMethod ;
4248 continue ;
4349 }
4450
51+ $ docComment = $ reflectionMethod ->getDocComment ();
52+ if ($ docComment !== false ) {
53+ $ methodPhpDoc = $ this ->fileTypeMapper ->getResolvedPhpDoc (
54+ $ scope ->getFile (),
55+ $ classReflection ->getName (),
56+ $ scope ->isInTrait () ? $ scope ->getTraitReflection ()->getName () : null ,
57+ $ reflectionMethod ->getName (),
58+ $ docComment ,
59+ );
60+
61+ if ($ this ->hasTestAnnotation ($ methodPhpDoc )) {
62+ $ testMethods [] = $ reflectionMethod ;
63+ continue ;
64+ }
65+ }
66+
4567 // todo: detect tests with @test annotation
4668
47- $ testAttributes = $ reflectionMethod ->getAttributes ('PHPUnit\Framework\Attribute\Test ' );
69+ // XXX
70+ //if (!$this->phpunit10OrNewer) {
71+ // return;
72+ //}
73+
74+ $ testAttributes = $ reflectionMethod ->getAttributes ('PHPUnit\Framework\Attributes\Test ' );
4875 if ($ testAttributes === []) {
4976 continue ;
5077 }
@@ -55,4 +82,22 @@ public function getTestMethods(ClassReflection $class): array
5582 return $ testMethods ;
5683 }
5784
85+ private function hasTestAnnotation (?ResolvedPhpDocBlock $ phpDoc ): bool
86+ {
87+ if ($ phpDoc === null ) {
88+ return false ;
89+ }
90+
91+ $ phpDocNodes = $ phpDoc ->getPhpDocNodes ();
92+
93+ foreach ($ phpDocNodes as $ docNode ) {
94+ $ tags = $ docNode ->getTagsByName ('@test ' );
95+ if ($ tags !== []) {
96+ return true ;
97+ }
98+ }
99+
100+ return false ;
101+ }
102+
58103}
0 commit comments