1
1
package io .testomat .junit .extractor .strategy .handlers ;
2
2
3
3
import io .testomat .junit .extractor .strategy .ParameterExtractionContext ;
4
+ import io .testomat .junit .util .ParameterizedTestSupport ;
5
+ import java .lang .annotation .Annotation ;
4
6
import java .lang .reflect .Method ;
5
7
import java .lang .reflect .Parameter ;
6
- import org .junit .jupiter .params .provider .EnumSource ;
7
8
8
9
/**
9
10
* Parameter extraction handler for @EnumSource annotated parameterized tests.
@@ -24,14 +25,31 @@ protected Object parseDisplayNameValue(String valueStr, ParameterExtractionConte
24
25
25
26
@ Override
26
27
protected Object extractFromAnnotation (ParameterExtractionContext context ) {
27
- EnumSource enumSource = context .getAnnotation (EnumSource .class );
28
- if (enumSource == null ) {
28
+ if (!ParameterizedTestSupport .isAvailable ()) {
29
29
return null ;
30
30
}
31
+
32
+ return ParameterizedTestSupport .loadAnnotationClass ("EnumSource" )
33
+ .map (enumSourceClass -> {
34
+ Annotation enumSource = context .getAnnotation (enumSourceClass );
35
+ if (enumSource == null ) {
36
+ return null ;
37
+ }
38
+ return extractValueFromEnumSource (enumSource , context );
39
+ })
40
+ .orElse (null );
41
+ }
42
+
43
+ private Object extractValueFromEnumSource (Annotation enumSource ,
44
+ ParameterExtractionContext context ) {
31
45
try {
32
- Class <? extends Enum <?>> enumClass = enumSource .value ();
46
+ Class <?> annotationClass = enumSource .annotationType ();
33
47
34
- if (enumClass .getName ().equals ("org.junit.jupiter.params.provider.NullEnum" )) {
48
+ java .lang .reflect .Method valueMethod = annotationClass .getMethod ("value" );
49
+ Class <? extends Enum <?>> enumClass =
50
+ (Class <? extends Enum <?>>) valueMethod .invoke (enumSource );
51
+
52
+ if (isNullEnum (enumClass )) {
35
53
enumClass = inferEnumClassFromMethod (context );
36
54
}
37
55
@@ -44,16 +62,11 @@ protected Object extractFromAnnotation(ParameterExtractionContext context) {
44
62
return null ;
45
63
}
46
64
47
- String [] names = enumSource .names ();
65
+ java .lang .reflect .Method namesMethod = annotationClass .getMethod ("names" );
66
+ String [] names = (String []) namesMethod .invoke (enumSource );
67
+
48
68
if (names .length > 0 ) {
49
- for (String name : names ) {
50
- try {
51
- return Enum .valueOf ((Class ) enumClass , name );
52
- } catch (IllegalArgumentException e ) {
53
- logger .warn ("Could not find enum constant {}" , name );
54
- }
55
- }
56
- return null ;
69
+ return findFirstValidEnumConstant (enumClass , names );
57
70
}
58
71
59
72
return enumConstants [0 ];
@@ -64,6 +77,22 @@ protected Object extractFromAnnotation(ParameterExtractionContext context) {
64
77
}
65
78
}
66
79
80
+ private boolean isNullEnum (Class <? extends Enum <?>> enumClass ) {
81
+ return enumClass .getName ().equals ("org.junit.jupiter.params.provider.NullEnum" );
82
+ }
83
+
84
+ private Object findFirstValidEnumConstant (Class <? extends Enum <?>> enumClass ,
85
+ String [] names ) {
86
+ for (String name : names ) {
87
+ try {
88
+ return Enum .valueOf ((Class ) enumClass , name );
89
+ } catch (IllegalArgumentException e ) {
90
+ logger .warn ("Could not find enum constant {}" , name );
91
+ }
92
+ }
93
+ return null ;
94
+ }
95
+
67
96
@ SuppressWarnings ("unchecked" )
68
97
private Class <? extends Enum <?>> inferEnumClassFromMethod (ParameterExtractionContext context ) {
69
98
Method method = context .getTestMethod ();
@@ -95,26 +124,52 @@ private Object parseEnumValue(String value, ParameterExtractionContext context)
95
124
return null ;
96
125
}
97
126
127
+ if (!ParameterizedTestSupport .isAvailable ()) {
128
+ return value ;
129
+ }
130
+
98
131
try {
99
- EnumSource enumSource = context .getAnnotation (EnumSource .class );
100
- Class <? extends Enum <?>> enumClass = enumSource .value ();
132
+ return ParameterizedTestSupport .loadAnnotationClass ("EnumSource" )
133
+ .map (enumSourceClass -> {
134
+ Annotation enumSource = context .getAnnotation (enumSourceClass );
135
+ if (enumSource == null ) {
136
+ return value ;
137
+ }
138
+ return parseEnumWithReflection (enumSource , trimmed , context );
139
+ })
140
+ .orElse (value );
141
+ } catch (Exception e ) {
142
+ logger .debug ("Failed to parse enum value: {}" , trimmed , e );
143
+ return value ;
144
+ }
145
+ }
101
146
102
- if (enumClass .getName ().equals ("org.junit.jupiter.params.provider.NullEnum" )) {
147
+ private Object parseEnumWithReflection (Annotation enumSource , String trimmed ,
148
+ ParameterExtractionContext context ) {
149
+ try {
150
+ Method valueMethod = enumSource .annotationType ().getMethod ("value" );
151
+ Class <? extends Enum <?>> enumClass =
152
+ (Class <? extends Enum <?>>) valueMethod .invoke (enumSource );
153
+
154
+ if (isNullEnum (enumClass )) {
103
155
enumClass = inferEnumClassFromMethod (context );
104
156
}
105
157
106
158
if (enumClass != null ) {
107
- String enumName = trimmed ;
108
- if (trimmed .contains ("." )) {
109
- enumName = trimmed .substring (trimmed .lastIndexOf ('.' ) + 1 );
110
- }
111
-
159
+ String enumName = extractEnumName (trimmed );
112
160
return Enum .valueOf ((Class ) enumClass , enumName );
113
161
}
114
162
} catch (Exception e ) {
115
- logger .debug ("Failed to parse enum value: {}" , trimmed , e );
163
+ logger .debug ("Failed to parse enum value with reflection : {}" , trimmed , e );
116
164
}
117
165
118
- return value ;
166
+ return trimmed ;
167
+ }
168
+
169
+ private String extractEnumName (String trimmed ) {
170
+ if (trimmed .contains ("." )) {
171
+ return trimmed .substring (trimmed .lastIndexOf ('.' ) + 1 );
172
+ }
173
+ return trimmed ;
119
174
}
120
175
}
0 commit comments