@@ -19,83 +19,69 @@ class DataProvider
1919{
2020 public static function getDataForMethod (ReflectionMethod $ method , ?ReflectionClass $ class = null , ?Actor $ I = null ): ?iterable
2121 {
22- $ testClass = self ::getTestClass ($ method , $ class );
22+ $ testClass = self ::getTestClass ($ method , $ class );
2323 $ testClassName = $ testClass ->getName ();
24- $ methodName = $ method ->getName ();
25-
26- // example annotation
27- $ rawExamples = array_values (
28- Annotation::forMethod ($ testClassName , $ methodName )->fetchAll ('example ' ),
29- );
24+ $ methodName = $ method ->getName ();
25+ $ annotation = Annotation::forMethod ($ testClassName , $ methodName );
3026
27+ $ data = [];
28+ $ rawExamples = $ annotation ->fetchAll ('example ' );
3129 if ($ rawExamples !== []) {
32- $ rawExample = reset ($ rawExamples );
33- if (is_string ($ rawExample )) {
34- $ result = array_map (
35- static fn ($ v ): ?array => Annotation::arrayValue ($ v ),
36- $ rawExamples
37- );
38- } else {
39- $ result = $ rawExamples ;
30+ $ convert = is_string (reset ($ rawExamples ));
31+ foreach ($ rawExamples as $ example ) {
32+ $ data [] = $ convert ? Annotation::arrayValue ($ example ) : $ example ;
4033 }
41- } else {
42- $ result = [];
4334 }
4435
45- // dataProvider annotation
46- $ dataProviderAnnotations = Annotation::forMethod ($ testClassName , $ methodName )->fetchAll ('dataProvider ' );
47- // lowercase for back compatible
48- if ($ dataProviderAnnotations === []) {
49- $ dataProviderAnnotations = Annotation::forMethod ($ testClassName , $ methodName )->fetchAll ('dataprovider ' );
50- }
36+ $ providers = array_merge (
37+ $ annotation ->fetchAll ('dataProvider ' ),
38+ $ annotation ->fetchAll ('dataprovider ' )
39+ );
5140
52- if ($ result === [] && $ dataProviderAnnotations === []) {
41+ if ($ data === [] && $ providers === []) {
5342 return null ;
5443 }
5544
56- foreach ($ dataProviderAnnotations as $ dataProviderAnnotation ) {
57- [$ dataProviderClassName , $ dataProviderMethodName ] = self ::parseDataProviderAnnotation (
58- $ dataProviderAnnotation ,
45+ foreach ($ providers as $ provider ) {
46+ [$ providerClass , $ providerMethod ] = self ::parseDataProviderAnnotation (
47+ $ provider ,
5948 $ testClassName ,
60- $ methodName,
49+ $ methodName
6150 );
6251
6352 try {
64- $ dataProviderMethod = new ReflectionMethod ($ dataProviderClassName , $ dataProviderMethodName );
65- if ($ dataProviderMethod ->isStatic ()) {
66- $ dataProviderResult = call_user_func ([$ dataProviderClassName , $ dataProviderMethodName ], $ I );
53+ $ refMethod = new ReflectionMethod ($ providerClass , $ providerMethod );
54+
55+ if ($ refMethod ->isStatic ()) {
56+ $ result = $ providerClass ::$ providerMethod ($ I );
6757 } else {
68- $ testInstance = new $ dataProviderClassName ($ dataProviderMethodName );
69-
70- if ($ dataProviderMethod ->isPublic ()) {
71- $ dataProviderResult = $ testInstance ->$ dataProviderMethodName ($ I );
72- } else {
73- $ dataProviderResult = ReflectionHelper::invokePrivateMethod (
74- $ testInstance ,
75- $ dataProviderMethodName ,
76- [$ I ]
77- );
78- }
58+ $ instance = new $ providerClass ($ providerMethod );
59+ $ result = $ refMethod ->isPublic ()
60+ ? $ instance ->$ providerMethod ($ I )
61+ : ReflectionHelper::invokePrivateMethod ($ instance , $ providerMethod , [$ I ]);
7962 }
8063
81- foreach ($ dataProviderResult as $ key => $ value ) {
82- if (is_int ($ key )) {
83- $ result [] = $ value ;
84- } else {
85- $ result [$ key ] = $ value ;
86- }
64+ if (!is_iterable ($ result )) {
65+ throw new InvalidTestException (
66+ "DataProvider ' {$ provider }' for {$ testClassName }:: {$ methodName } " .
67+ 'must return iterable data, got ' . gettype ($ result )
68+ );
8769 }
88- } catch (ReflectionException ) {
70+
71+ foreach ($ result as $ key => $ value ) {
72+ is_int ($ key ) ? $ data [] = $ value : $ data [$ key ] = $ value ;
73+ }
74+ } catch (ReflectionException $ e ) {
8975 throw new InvalidTestException (sprintf (
9076 "DataProvider '%s' for %s::%s is invalid or not callable " ,
91- $ dataProviderAnnotation ,
77+ $ provider ,
9278 $ testClassName ,
9379 $ methodName
94- ));
80+ ), 0 , $ e );
9581 }
9682 }
9783
98- return $ result ;
84+ return $ data ?: null ;
9985 }
10086
10187 /**
@@ -108,37 +94,30 @@ public static function parseDataProviderAnnotation(
10894 string $ testMethodName ,
10995 ): array {
11096 $ parts = explode (':: ' , $ annotation );
111- if (count ($ parts ) > 2 ) {
112- throw new InvalidTestException (
113- sprintf (
114- 'Data provider "%s" specified for %s::%s is invalid ' ,
115- $ annotation ,
116- $ testClassName ,
117- $ testMethodName ,
118- )
119- );
120- }
12197
122- if (count ($ parts ) === 2 ) {
98+ if (count ($ parts ) === 2 && $ parts [ 0 ] !== '' ) {
12399 return $ parts ;
124100 }
101+ if (count ($ parts ) === 1 || $ parts [0 ] === '' ) {
102+ return [$ testClassName , ltrim ($ parts [1 ] ?? $ parts [0 ], ': ' )];
103+ }
125104
126- return [
127- $ testClassName ,
105+ throw new InvalidTestException ( sprintf (
106+ ' Data provider "%s" specified for %s::%s is invalid ' ,
128107 $ annotation ,
129- ];
108+ $ testClassName ,
109+ $ testMethodName
110+ ));
130111 }
131112
132- /**
133- * Retrieves actual test class for dataProvider.
134- */
135- private static function getTestClass (ReflectionMethod $ dataProviderMethod , ?ReflectionClass $ testClass ): ReflectionClass
113+ private static function getTestClass (ReflectionMethod $ method , ?ReflectionClass $ class ): ReflectionClass
136114 {
137- $ dataProviderDeclaringClass = $ dataProviderMethod ->getDeclaringClass ();
138- // data provider in abstract class?
139- if ($ dataProviderDeclaringClass ->isAbstract () && $ testClass instanceof ReflectionClass && $ dataProviderDeclaringClass ->name !== $ testClass ->name ) {
140- return $ testClass ;
141- }
142- return $ dataProviderDeclaringClass ;
115+ $ declaringClass = $ method ->getDeclaringClass ();
116+
117+ return $ declaringClass ->isAbstract ()
118+ && $ class instanceof ReflectionClass
119+ && $ declaringClass ->getName () !== $ class ->getName ()
120+ ? $ class
121+ : $ declaringClass ;
143122 }
144123}
0 commit comments