17
17
import static org .junit .platform .commons .util .CollectionUtils .forEachInReverseOrder ;
18
18
19
19
import java .lang .reflect .Method ;
20
+ import java .util .ArrayList ;
20
21
import java .util .Collections ;
21
22
import java .util .LinkedHashSet ;
22
23
import java .util .List ;
39
40
import org .junit .platform .commons .util .Preconditions ;
40
41
import org .junit .platform .commons .util .ReflectionUtils ;
41
42
import org .junit .platform .commons .util .UnrecoverableExceptions ;
43
+ import org .junit .platform .engine .DiscoveryIssue ;
42
44
import org .junit .platform .engine .TestDescriptor ;
43
45
import org .junit .platform .engine .TestTag ;
44
46
import org .junit .platform .engine .UniqueId ;
45
47
import org .junit .platform .engine .support .descriptor .MethodSource ;
48
+ import org .junit .platform .engine .support .discovery .DiscoveryIssueReporter ;
46
49
47
50
/**
48
51
* Base class for {@link TestDescriptor TestDescriptors} based on Java methods.
51
54
*/
52
55
@ API (status = INTERNAL , since = "5.0" )
53
56
public abstract class MethodBasedTestDescriptor extends JupiterTestDescriptor
54
- implements ResourceLockAware , TestClassAware {
57
+ implements ResourceLockAware , TestClassAware , Validatable {
55
58
56
59
private static final Logger logger = LoggerFactory .getLogger (MethodBasedTestDescriptor .class );
57
60
58
- private final Class <?> testClass ;
59
- private final Method testMethod ;
60
-
61
- /**
62
- * Set of method-level tags; does not contain tags from parent.
63
- */
64
- private final Set <TestTag > tags ;
61
+ private final MethodInfo methodInfo ;
65
62
66
63
MethodBasedTestDescriptor (UniqueId uniqueId , Class <?> testClass , Method testMethod ,
67
64
Supplier <List <Class <?>>> enclosingInstanceTypes , JupiterConfiguration configuration ) {
@@ -72,21 +69,54 @@ public abstract class MethodBasedTestDescriptor extends JupiterTestDescriptor
72
69
MethodBasedTestDescriptor (UniqueId uniqueId , String displayName , Class <?> testClass , Method testMethod ,
73
70
JupiterConfiguration configuration ) {
74
71
super (uniqueId , displayName , MethodSource .from (testClass , testMethod ), configuration );
72
+ this .methodInfo = new MethodInfo (testClass , testMethod );
73
+ }
75
74
76
- this .testClass = Preconditions .notNull (testClass , "Class must not be null" );
77
- this .testMethod = testMethod ;
78
- this .tags = getTags (testMethod ,
79
- builder -> logger .warn (() -> "Configuration error: " + builder .build ().message ()));
75
+ public final Method getTestMethod () {
76
+ return this .methodInfo .testMethod ;
80
77
}
81
78
79
+ // --- TestDescriptor ------------------------------------------------------
80
+
82
81
@ Override
83
82
public final Set <TestTag > getTags () {
84
83
// return modifiable copy
85
- Set <TestTag > allTags = new LinkedHashSet <>(this .tags );
84
+ Set <TestTag > allTags = new LinkedHashSet <>(this .methodInfo . tags );
86
85
getParent ().ifPresent (parentDescriptor -> allTags .addAll (parentDescriptor .getTags ()));
87
86
return allTags ;
88
87
}
89
88
89
+ @ Override
90
+ public String getLegacyReportingName () {
91
+ return String .format ("%s(%s)" , getTestMethod ().getName (),
92
+ ClassUtils .nullSafeToString (Class ::getSimpleName , getTestMethod ().getParameterTypes ()));
93
+ }
94
+
95
+ // --- TestClassAware ------------------------------------------------------
96
+
97
+ @ Override
98
+ public final Class <?> getTestClass () {
99
+ return this .methodInfo .testClass ;
100
+ }
101
+
102
+ @ Override
103
+ public List <Class <?>> getEnclosingTestClasses () {
104
+ return getParent () //
105
+ .filter (TestClassAware .class ::isInstance ) //
106
+ .map (TestClassAware .class ::cast ) //
107
+ .map (TestClassAware ::getEnclosingTestClasses ) //
108
+ .orElseGet (Collections ::emptyList );
109
+ }
110
+
111
+ // --- Validatable ---------------------------------------------------------
112
+
113
+ @ Override
114
+ public void validate (DiscoveryIssueReporter reporter ) {
115
+ Validatable .reportAndClear (this .methodInfo .discoveryIssues , reporter );
116
+ }
117
+
118
+ // --- Node ----------------------------------------------------------------
119
+
90
120
@ Override
91
121
public ExclusiveResourceCollector getExclusiveResourceCollector () {
92
122
// There's no need to cache this as this method should only be called once
@@ -108,34 +138,11 @@ public Function<ResourceLocksProvider, Set<ResourceLocksProvider.Lock>> getResou
108
138
getTestMethod ()));
109
139
}
110
140
111
- @ Override
112
- public List <Class <?>> getEnclosingTestClasses () {
113
- return getParent () //
114
- .filter (TestClassAware .class ::isInstance ) //
115
- .map (TestClassAware .class ::cast ) //
116
- .map (TestClassAware ::getEnclosingTestClasses ) //
117
- .orElseGet (Collections ::emptyList );
118
- }
119
-
120
141
@ Override
121
142
protected Optional <ExecutionMode > getExplicitExecutionMode () {
122
143
return getExecutionModeFromAnnotation (getTestMethod ());
123
144
}
124
145
125
- public final Class <?> getTestClass () {
126
- return this .testClass ;
127
- }
128
-
129
- public final Method getTestMethod () {
130
- return this .testMethod ;
131
- }
132
-
133
- @ Override
134
- public String getLegacyReportingName () {
135
- return String .format ("%s(%s)" , testMethod .getName (),
136
- ClassUtils .nullSafeToString (Class ::getSimpleName , testMethod .getParameterTypes ()));
137
- }
138
-
139
146
/**
140
147
* Invoke {@link TestWatcher#testDisabled(ExtensionContext, Optional)} on each
141
148
* registered {@link TestWatcher}, in registration order.
@@ -181,4 +188,27 @@ protected void invokeTestWatchers(JupiterEngineExecutionContext context, boolean
181
188
}
182
189
}
183
190
191
+ private static class MethodInfo {
192
+
193
+ private final List <DiscoveryIssue > discoveryIssues = new ArrayList <>();
194
+
195
+ private final Class <?> testClass ;
196
+ private final Method testMethod ;
197
+
198
+ /**
199
+ * Set of method-level tags; does not contain tags from parent.
200
+ */
201
+ private final Set <TestTag > tags ;
202
+
203
+ MethodInfo (Class <?> testClass , Method testMethod ) {
204
+ this .testClass = Preconditions .notNull (testClass , "Class must not be null" );
205
+ this .testMethod = testMethod ;
206
+ this .tags = getTags (testMethod , //
207
+ () -> String .format ("method '%s'" , testMethod .toGenericString ()), //
208
+ // Use _declaring_ class here because that's where the `@Tag` annotation is declared
209
+ () -> MethodSource .from (testMethod .getDeclaringClass (), testMethod ), //
210
+ discoveryIssues ::add );
211
+ }
212
+ }
213
+
184
214
}
0 commit comments