@@ -115,18 +115,18 @@ public function refactor(Node $node): ?Node
115115 $ currentMethodName = $ this ->getName ($ classMethod );
116116
117117 foreach ($ desiredTagValueNodes as $ desiredTagValueNode ) {
118- $ attributeNameAndValue = $ this ->resolveAttributeNameAndValue (
118+ $ attributeNameAndItems = $ this ->resolveAttributeNameAndItems (
119119 $ desiredTagValueNode ,
120120 $ node ,
121121 $ currentMethodName
122122 );
123- if ($ attributeNameAndValue === []) {
123+ if ($ attributeNameAndItems === []) {
124124 continue ;
125125 }
126126
127127 $ attributeGroup = $ this ->phpAttributeGroupFactory ->createFromClassWithItems (
128- $ attributeNameAndValue [0 ],
129- [ $ attributeNameAndValue [ 1 ] ]
128+ $ attributeNameAndItems [0 ],
129+ $ attributeNameAndItems [ 1 ]
130130 );
131131 $ classMethod ->attrGroups [] = $ attributeGroup ;
132132
@@ -146,9 +146,9 @@ public function refactor(Node $node): ?Node
146146 }
147147
148148 /**
149- * @return string[]
149+ * @return array{ string, string[]}|array{}
150150 */
151- private function resolveAttributeNameAndValue (
151+ private function resolveAttributeNameAndItems (
152152 PhpDocTagNode $ phpDocTagNode ,
153153 Class_ $ class ,
154154 string $ currentMethodName
@@ -158,23 +158,23 @@ private function resolveAttributeNameAndValue(
158158 }
159159
160160 $ originalAttributeValue = $ phpDocTagNode ->value ->value ;
161- $ attributeNameAndValue = $ this ->resolveAttributeValueAndAttributeName (
161+ $ attributeNameAndItems = $ this ->resolveAttributeNameAndItemsFromValue (
162162 $ class ,
163163 $ currentMethodName ,
164164 $ originalAttributeValue
165165 );
166166
167- if ($ attributeNameAndValue === null ) {
167+ if ($ attributeNameAndItems === null ) {
168168 return [];
169169 }
170170
171- return $ attributeNameAndValue ;
171+ return $ attributeNameAndItems ;
172172 }
173173
174174 /**
175- * @return string[] |null
175+ * @return array{ string, string[]} |null
176176 */
177- private function resolveAttributeValueAndAttributeName (
177+ private function resolveAttributeNameAndItemsFromValue (
178178 Class_ $ currentClass ,
179179 string $ currentMethodName ,
180180 string $ originalAttributeValue
@@ -185,29 +185,57 @@ private function resolveAttributeValueAndAttributeName(
185185 $ currentMethodName ,
186186 $ originalAttributeValue
187187 );
188+ if (is_string ($ attributeValue )) {
189+ return [self ::DEPENDS_ATTRIBUTE , [$ attributeValue ]];
190+ }
188191
189- $ attributeName = self ::DEPENDS_ATTRIBUTE ;
190- if (! is_string ($ attributeValue )) {
191- // other: depends other Class_
192- $ attributeValue = $ this ->resolveDependsClass ($ originalAttributeValue );
193- $ attributeName = 'PHPUnit\Framework\Attributes\DependsOnClass ' ;
192+ // other: depends other Class_
193+ $ attributeValue = $ this ->resolveDependsClass ($ originalAttributeValue );
194+ if (is_string ($ attributeValue )) {
195+ return ['PHPUnit\Framework\Attributes\DependsOnClass ' , [$ attributeValue ]];
194196 }
195197
196- if (! is_string ( $ attributeValue )) {
197- // other: depends clone ClassMethod
198- $ attributeValue = $ this -> resolveDependsCloneClassMethod (
199- $ currentClass ,
200- $ currentMethodName ,
201- $ originalAttributeValue
202- );
203- $ attributeName = 'PHPUnit\Framework\Attributes\DependsUsingDeepClone ' ;
198+ // other: depends clone ClassMethod
199+ $ attributeValue = $ this -> resolveDependsCloneClassMethod (
200+ $ currentClass ,
201+ $ currentMethodName ,
202+ $ originalAttributeValue
203+ );
204+ if ( is_string ( $ attributeValue )) {
205+ return [ 'PHPUnit\Framework\Attributes\DependsUsingDeepClone ' , [ $ attributeValue ]] ;
204206 }
205207
206- if (! is_string ($ attributeValue )) {
208+ // other: depends external ClassMethod, e.g. "OtherTest::testMethod"
209+ $ externalItems = $ this ->resolveDependsExternalClassMethod ($ originalAttributeValue );
210+ if ($ externalItems !== null ) {
211+ return ['PHPUnit\Framework\Attributes\DependsExternal ' , $ externalItems ];
212+ }
213+
214+ return null ;
215+ }
216+
217+ /**
218+ * @return string[]|null
219+ */
220+ private function resolveDependsExternalClassMethod (string $ attributeValue ): ?array
221+ {
222+ // deep clone variant is handled separately
223+ if (str_starts_with ($ attributeValue , 'clone ' )) {
224+ return null ;
225+ }
226+
227+ if (! str_contains ($ attributeValue , ':: ' )) {
228+ return null ;
229+ }
230+
231+ [$ className , $ methodName ] = explode (':: ' , $ attributeValue , 2 );
232+
233+ // "::class" is handled as DependsOnClass
234+ if ($ className === '' || $ methodName === '' || $ methodName === 'class ' ) {
207235 return null ;
208236 }
209237
210- return [$ attributeName , $ attributeValue ];
238+ return [$ className . ' ::class ' , $ methodName ];
211239 }
212240
213241 private function resolveDependsClass (string $ attributeValue ): ?string
0 commit comments