Skip to content

Commit ec1f1d7

Browse files
committed
Introduce ClassOrderer.Default for reverting back to default ordering
1 parent a34e5a1 commit ec1f1d7

File tree

7 files changed

+94
-5
lines changed

7 files changed

+94
-5
lines changed

documentation/src/docs/asciidoc/link-attributes.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ endif::[]
112112
:Assumptions: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/Assumptions.html[org.junit.jupiter.api.Assumptions]
113113
:AutoClose: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/AutoClose.html[@AutoClose]
114114
:ClassOrderer_ClassName: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ClassOrderer.ClassName.html[ClassOrderer.ClassName]
115+
:ClassOrderer_Default: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ClassOrderer.Default.html[ClassOrderer.Default]
115116
:ClassOrderer_DisplayName: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ClassOrderer.DisplayName.html[ClassOrderer.DisplayName]
116117
:ClassOrderer_OrderAnnotation: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ClassOrderer.OrderAnnotation.html[ClassOrderer.OrderAnnotation]
117118
:ClassOrderer_Random: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ClassOrderer.Random.html[ClassOrderer.Random]

documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-RC1.adoc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ repository on GitHub.
7474
<<../user-guide/index.adoc#writing-tests-display-names, User Guide>> for details.
7575
* For consistency with `@TestClassOrder`, `@TestMethodOrder` annotations specified on a
7676
test class are now inherited to its `@Nested` inner classes, recursively.
77-
* Introduce `MethodOrderer.Default` for reverting back to default ordering on a `@Nested`
78-
class, recursively, when an enclosing class specifies a different method orderer via
79-
`@TestMethodOrder`.
77+
* Introduce `MethodOrderer.Default` and `ClassOrderer.Default` for reverting back to
78+
default ordering on a `@Nested` class and its `@Nested` inner classes when an enclosing
79+
class specifies a different orderer via `@TestMethodOrder` or `@TestClassOrder`,
80+
respectively.
8081

8182

8283
[[release-notes-6.0.0-RC1-junit-vintage]]

documentation/src/docs/asciidoc/user-guide/writing-tests.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,8 @@ To configure test class execution order _locally_ for `@Nested` test classes, de
11301130
want to order, and supply a class reference to the `ClassOrderer` implementation you would
11311131
like to use directly in the `@TestClassOrder` annotation. The configured `ClassOrderer`
11321132
will be applied recursively to `@Nested` test classes and their `@Nested` test classes.
1133+
If you want to avoid that a `@Nested` test class uses the same `ClassOrderer` as its
1134+
enclosing class, you can specify `{ClassOrderer_Default}` together with `@TestClassOrder`.
11331135
Note that a local `@TestClassOrder` declaration always overrides an inherited
11341136
`@TestClassOrder` declaration or a `ClassOrderer` configured globally via the
11351137
`junit.jupiter.testclass.order.default` configuration parameter.

junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrderer.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
package org.junit.jupiter.api;
1212

1313
import static java.util.Comparator.comparingInt;
14+
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
1415
import static org.apiguardian.api.API.Status.STABLE;
1516

1617
import java.util.Collections;
1718
import java.util.Comparator;
1819

1920
import org.apiguardian.api.API;
21+
import org.junit.platform.commons.JUnitException;
2022
import org.junit.platform.commons.logging.Logger;
2123
import org.junit.platform.commons.logging.LoggerFactory;
2224

@@ -51,6 +53,9 @@
5153
* <li>{@link ClassOrderer.Random}</li>
5254
* </ul>
5355
*
56+
* <p>In addition, {@link ClassOrderer.Default} allows reverting back to default ordering for
57+
* {@link Nested @Nested} classes.
58+
*
5459
* @since 5.8
5560
* @see TestClassOrder
5661
* @see ClassOrdererContext
@@ -97,6 +102,35 @@ public interface ClassOrderer {
97102
*/
98103
void orderClasses(ClassOrdererContext context);
99104

105+
/**
106+
* {@code ClassOrderer} that allows to explicitly specify that the default
107+
* ordering should be applied.
108+
*
109+
* <p>If the {@value #DEFAULT_ORDER_PROPERTY_NAME} is set, specifying this
110+
* {@code ClassOrderer} has the same effect as referencing the configured
111+
* class directly. Otherwise, it has the same effect as not specifying any
112+
* {@code ClassOrderer}.
113+
*
114+
* <p>This annotation is useful to reset the {@code ClassOrderer} for a
115+
* {@link Nested @Nested} class and its {@code @Nested} inner classes,
116+
* recursively, when a {@code ClassOrderer} is configured using
117+
* {@link TestClassOrder @TestClassOrder} on an enclosing class.
118+
*
119+
* @since 6.0
120+
*/
121+
@API(status = EXPERIMENTAL, since = "6.0")
122+
final class Default implements ClassOrderer {
123+
124+
private Default() {
125+
throw new JUnitException("This class must not be instantiated");
126+
}
127+
128+
@Override
129+
public void orderClasses(ClassOrdererContext context) {
130+
// never called
131+
}
132+
}
133+
100134
/**
101135
* {@code ClassOrderer} that sorts classes alphanumerically based on their
102136
* fully qualified names using {@link String#compareTo(String)}.

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/config/DefaultJupiterConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ public class DefaultJupiterConfiguration implements JupiterConfiguration {
6969
new InstantiatingConfigurationParameterConverter<>(MethodOrderer.class, "method orderer"));
7070

7171
private static final ConfigurationParameterConverter<ClassOrderer> classOrdererConverter = //
72-
new InstantiatingConfigurationParameterConverter<>(ClassOrderer.class, "class orderer");
72+
exclude(isEqual(ClassOrderer.Default.class.getName()),
73+
new InstantiatingConfigurationParameterConverter<>(ClassOrderer.class, "class orderer"));
7374

7475
private static final ConfigurationParameterConverter<CleanupMode> cleanupModeConverter = //
7576
new EnumConfigurationParameterConverter<>(CleanupMode.class, "cleanup mode");

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/discovery/ClassOrderingVisitor.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ private DescriptorWrapperOrderer<TestDescriptor, ClassOrderer, DefaultClassDescr
113113
ClassBasedTestDescriptor classBasedTestDescriptor) {
114114
return AnnotationSupport.findAnnotation(classBasedTestDescriptor.getTestClass(), TestClassOrder.class)//
115115
.map(TestClassOrder::value)//
116-
.map(ReflectionSupport::newInstance)//
117116
.map(this::createDescriptorWrapperOrderer)//
118117
.orElseGet(() -> {
119118
Object parent = classBasedTestDescriptor.getParent().orElse(null);
@@ -125,6 +124,14 @@ private DescriptorWrapperOrderer<TestDescriptor, ClassOrderer, DefaultClassDescr
125124
});
126125
}
127126

127+
private DescriptorWrapperOrderer<TestDescriptor, ClassOrderer, DefaultClassDescriptor> createDescriptorWrapperOrderer(
128+
Class<? extends ClassOrderer> ordererClass) {
129+
if (ordererClass == ClassOrderer.Default.class) {
130+
return globalOrderer;
131+
}
132+
return createDescriptorWrapperOrderer(ReflectionSupport.newInstance(ordererClass));
133+
}
134+
128135
private DescriptorWrapperOrderer<TestDescriptor, ClassOrderer, DefaultClassDescriptor> createDescriptorWrapperOrderer(
129136
ClassOrderer classOrderer) {
130137
OrderingAction<TestDescriptor, DefaultClassDescriptor> orderingAction = (__,

jupiter-tests/src/test/java/org/junit/jupiter/engine/extension/OrderedClassTests.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,24 @@ void classTemplateWithGlobalConfig() {
200200
.containsSubsequence(classTemplate.getSimpleName(), otherClass.getSimpleName());
201201
}
202202

203+
@Test
204+
void nestedClassedCanUseDefaultOrder(@TrackLogRecords LogRecordListener logRecords) {
205+
executeTests(null, selectClass(RevertingBackToDefaultOrderTestCase.Inner.class));
206+
assertThat(callSequence).containsExactly("ShortName", "AMuchLongerNameForSure");
207+
callSequence.clear();
208+
209+
executeTests(ClassOrderer.ClassName.class, selectClass(RevertingBackToDefaultOrderTestCase.Inner.class));
210+
assertThat(callSequence).containsExactly("AMuchLongerNameForSure", "ShortName");
211+
callSequence.clear();
212+
213+
executeTests(ClassOrderer.Default.class, selectClass(RevertingBackToDefaultOrderTestCase.Inner.class));
214+
assertThat(callSequence).containsExactly("ShortName", "AMuchLongerNameForSure");
215+
assertThat(logRecords.stream()) //
216+
.filteredOn(it -> it.getLevel().intValue() >= Level.WARNING.intValue()) //
217+
.map(LogRecord::getMessage) //
218+
.isEmpty();
219+
}
220+
203221
private static void assertIneffectiveOrderAnnotationIssues(List<DiscoveryIssue> discoveryIssues) {
204222
assertThat(discoveryIssues).hasSize(2);
205223
assertThat(discoveryIssues).extracting(DiscoveryIssue::severity).containsOnly(Severity.INFO);
@@ -437,4 +455,29 @@ private record Ctx() implements ClassTemplateInvocationContext {
437455
}
438456
}
439457

458+
@TestClassOrder(ClassOrderer.DisplayName.class)
459+
static class RevertingBackToDefaultOrderTestCase {
460+
461+
@Nested
462+
@TestClassOrder(ClassOrderer.Default.class)
463+
class Inner {
464+
465+
@Nested
466+
class ShortName {
467+
@Test
468+
void test() {
469+
callSequence.add(getClass().getSimpleName());
470+
}
471+
}
472+
473+
@Nested
474+
class AMuchLongerNameForSure {
475+
@Test
476+
void test() {
477+
callSequence.add(getClass().getSimpleName());
478+
}
479+
}
480+
}
481+
}
482+
440483
}

0 commit comments

Comments
 (0)