11
11
package org .junit .jupiter .engine .discovery ;
12
12
13
13
import static org .junit .platform .commons .support .AnnotationSupport .findAnnotation ;
14
+ import static org .junit .platform .commons .support .AnnotationSupport .isAnnotated ;
14
15
15
16
import java .util .List ;
16
17
import java .util .Optional ;
17
18
import java .util .function .Consumer ;
18
19
19
20
import org .junit .jupiter .api .MethodOrderer ;
21
+ import org .junit .jupiter .api .Order ;
20
22
import org .junit .jupiter .api .TestMethodOrder ;
21
23
import org .junit .jupiter .engine .config .JupiterConfiguration ;
22
24
import org .junit .jupiter .engine .descriptor .ClassBasedTestDescriptor ;
23
25
import org .junit .jupiter .engine .descriptor .JupiterTestDescriptor ;
24
26
import org .junit .jupiter .engine .descriptor .MethodBasedTestDescriptor ;
25
27
import org .junit .platform .commons .support .ReflectionSupport ;
28
+ import org .junit .platform .engine .DiscoveryIssue ;
29
+ import org .junit .platform .engine .DiscoveryIssue .Severity ;
26
30
import org .junit .platform .engine .TestDescriptor ;
31
+ import org .junit .platform .engine .support .descriptor .MethodSource ;
32
+ import org .junit .platform .engine .support .discovery .DiscoveryIssueReporter ;
33
+ import org .junit .platform .engine .support .discovery .DiscoveryIssueReporter .Condition ;
27
34
28
35
/**
29
36
* @since 5.5
30
37
*/
31
38
class MethodOrderingVisitor extends AbstractOrderingVisitor {
32
39
33
40
private final JupiterConfiguration configuration ;
41
+ private final Condition <MethodBasedTestDescriptor > noOrderAnnotation ;
34
42
35
- MethodOrderingVisitor (JupiterConfiguration configuration ) {
43
+ MethodOrderingVisitor (JupiterConfiguration configuration , DiscoveryIssueReporter issueReporter ) {
36
44
this .configuration = configuration ;
45
+ this .noOrderAnnotation = issueReporter .createReportingCondition (
46
+ testDescriptor -> !isAnnotated (testDescriptor .getTestMethod (), Order .class ), testDescriptor -> {
47
+ String message = String .format (
48
+ "Ineffective @Order annotation on method '%s'. It will not be applied because MethodOrderer.OrderAnnotation is not in use." ,
49
+ testDescriptor .getTestMethod ().toGenericString ());
50
+ return DiscoveryIssue .builder (Severity .INFO , message ) //
51
+ .source (MethodSource .from (testDescriptor .getTestMethod ())) //
52
+ .build ();
53
+ });
37
54
}
38
55
39
56
@ Override
@@ -54,37 +71,62 @@ protected boolean shouldNonMatchingDescriptorsComeBeforeOrderedOnes() {
54
71
* @since 5.4
55
72
*/
56
73
private void orderContainedMethods (ClassBasedTestDescriptor classBasedTestDescriptor , Class <?> testClass ) {
57
- findAnnotation (testClass , TestMethodOrder .class )//
74
+ Optional < MethodOrderer > methodOrderer = findAnnotation (testClass , TestMethodOrder .class )//
58
75
.map (TestMethodOrder ::value )//
59
76
.<MethodOrderer > map (ReflectionSupport ::newInstance )//
60
77
.map (Optional ::of )//
61
- .orElseGet (configuration ::getDefaultTestMethodOrderer )//
62
- .ifPresent (methodOrderer -> {
63
-
64
- Consumer <List <DefaultMethodDescriptor >> orderingAction = methodDescriptors -> methodOrderer .orderMethods (
65
- new DefaultMethodOrdererContext (testClass , methodDescriptors , this .configuration ));
66
-
67
- MessageGenerator descriptorsAddedMessageGenerator = number -> String .format (
68
- "MethodOrderer [%s] added %s MethodDescriptor(s) for test class [%s] which will be ignored." ,
69
- methodOrderer .getClass ().getName (), number , testClass .getName ());
70
- MessageGenerator descriptorsRemovedMessageGenerator = number -> String .format (
71
- "MethodOrderer [%s] removed %s MethodDescriptor(s) for test class [%s] which will be retained with arbitrary ordering." ,
72
- methodOrderer .getClass ().getName (), number , testClass .getName ());
73
-
74
- DescriptorWrapperOrderer <DefaultMethodDescriptor > descriptorWrapperOrderer = new DescriptorWrapperOrderer <>(
75
- orderingAction , descriptorsAddedMessageGenerator , descriptorsRemovedMessageGenerator );
76
-
77
- orderChildrenTestDescriptors (classBasedTestDescriptor , //
78
- MethodBasedTestDescriptor .class , //
79
- DefaultMethodDescriptor ::new , //
80
- descriptorWrapperOrderer );
81
-
82
- // Note: MethodOrderer#getDefaultExecutionMode() is guaranteed
83
- // to be invoked after MethodOrderer#orderMethods().
84
- methodOrderer .getDefaultExecutionMode ()//
85
- .map (JupiterTestDescriptor ::toExecutionMode )//
86
- .ifPresent (classBasedTestDescriptor ::setDefaultChildExecutionMode );
87
- });
78
+ .orElseGet (configuration ::getDefaultTestMethodOrderer );
79
+ orderContainedMethods (classBasedTestDescriptor , testClass , methodOrderer );
80
+ }
81
+
82
+ private void orderContainedMethods (ClassBasedTestDescriptor classBasedTestDescriptor , Class <?> testClass ,
83
+ Optional <MethodOrderer > methodOrderer ) {
84
+ DescriptorWrapperOrderer <?, DefaultMethodDescriptor > descriptorWrapperOrderer = createDescriptorWrapperOrderer (
85
+ testClass , methodOrderer );
86
+
87
+ orderChildrenTestDescriptors (classBasedTestDescriptor , //
88
+ MethodBasedTestDescriptor .class , //
89
+ toValidationAction (methodOrderer ), //
90
+ DefaultMethodDescriptor ::new , //
91
+ descriptorWrapperOrderer );
92
+
93
+ // Note: MethodOrderer#getDefaultExecutionMode() is guaranteed
94
+ // to be invoked after MethodOrderer#orderMethods().
95
+ methodOrderer //
96
+ .flatMap (it -> it .getDefaultExecutionMode ().map (JupiterTestDescriptor ::toExecutionMode )) //
97
+ .ifPresent (classBasedTestDescriptor ::setDefaultChildExecutionMode );
98
+ }
99
+
100
+ private DescriptorWrapperOrderer <?, DefaultMethodDescriptor > createDescriptorWrapperOrderer (Class <?> testClass ,
101
+ Optional <MethodOrderer > methodOrderer ) {
102
+
103
+ return methodOrderer //
104
+ .map (it -> createDescriptorWrapperOrderer (testClass , it )) //
105
+ .orElseGet (DescriptorWrapperOrderer ::noop );
106
+
107
+ }
108
+
109
+ private DescriptorWrapperOrderer <?, DefaultMethodDescriptor > createDescriptorWrapperOrderer (Class <?> testClass ,
110
+ MethodOrderer methodOrderer ) {
111
+ Consumer <List <DefaultMethodDescriptor >> orderingAction = methodDescriptors -> methodOrderer .orderMethods (
112
+ new DefaultMethodOrdererContext (testClass , methodDescriptors , this .configuration ));
113
+
114
+ MessageGenerator descriptorsAddedMessageGenerator = number -> String .format (
115
+ "MethodOrderer [%s] added %s MethodDescriptor(s) for test class [%s] which will be ignored." ,
116
+ methodOrderer .getClass ().getName (), number , testClass .getName ());
117
+ MessageGenerator descriptorsRemovedMessageGenerator = number -> String .format (
118
+ "MethodOrderer [%s] removed %s MethodDescriptor(s) for test class [%s] which will be retained with arbitrary ordering." ,
119
+ methodOrderer .getClass ().getName (), number , testClass .getName ());
120
+
121
+ return new DescriptorWrapperOrderer <>(methodOrderer , orderingAction , descriptorsAddedMessageGenerator ,
122
+ descriptorsRemovedMessageGenerator );
123
+ }
124
+
125
+ private Optional <Consumer <MethodBasedTestDescriptor >> toValidationAction (Optional <MethodOrderer > methodOrderer ) {
126
+ if (methodOrderer .orElse (null ) instanceof MethodOrderer .OrderAnnotation ) {
127
+ return Optional .empty ();
128
+ }
129
+ return Optional .of (noOrderAnnotation ::check );
88
130
}
89
131
90
132
}
0 commit comments