Skip to content

Commit 449375e

Browse files
committed
Avoid reporting the same discovery issues multiple times
When encountering a method through different subclasses multiple times, any encountered discovery issues are now only reported once.
1 parent 5297565 commit 449375e

File tree

5 files changed

+69
-6
lines changed

5 files changed

+69
-6
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.jupiter.engine.discovery.predicates.IsTestClassWithTests;
2020
import org.junit.platform.engine.EngineDiscoveryRequest;
2121
import org.junit.platform.engine.TestDescriptor;
22+
import org.junit.platform.engine.support.discovery.DiscoveryIssueReporter;
2223
import org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver;
2324
import org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.InitializationContext;
2425

@@ -56,7 +57,9 @@ private static JupiterConfiguration getConfiguration(InitializationContext<Jupit
5657
}
5758

5859
public void resolveSelectors(EngineDiscoveryRequest request, JupiterEngineDescriptor engineDescriptor) {
59-
resolver.resolve(request, engineDescriptor);
60+
DiscoveryIssueReporter issueReporter = DiscoveryIssueReporter.deduplicating(
61+
DiscoveryIssueReporter.forwarding(request.getDiscoveryListener(), engineDescriptor.getUniqueId()));
62+
resolver.resolve(request, engineDescriptor, issueReporter);
6063
}
6164

6265
}

junit-platform-engine/src/main/java/org/junit/platform/engine/support/discovery/DiscoveryIssueReporter.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
1414

15+
import java.util.HashSet;
16+
import java.util.Set;
1517
import java.util.function.Consumer;
1618
import java.util.function.Function;
1719
import java.util.function.Predicate;
@@ -41,12 +43,31 @@ public interface DiscoveryIssueReporter {
4143
* {@code null}
4244
* @param engineId the unique identifier of the engine; never {@code null}
4345
*/
44-
static DiscoveryIssueReporter create(EngineDiscoveryListener engineDiscoveryListener, UniqueId engineId) {
46+
static DiscoveryIssueReporter forwarding(EngineDiscoveryListener engineDiscoveryListener, UniqueId engineId) {
4547
Preconditions.notNull(engineDiscoveryListener, "engineDiscoveryListener must not be null");
4648
Preconditions.notNull(engineId, "engineId must not be null");
4749
return issue -> engineDiscoveryListener.issueEncountered(engineId, issue);
4850
}
4951

52+
/**
53+
* Create a new {@code DiscoveryIssueReporter} that avoids reporting
54+
* duplicate issues.
55+
*
56+
* <p>The implementation returned by this method is not thread-safe.
57+
*
58+
* @param delegate the delegate to forward issues to; never {@code null}
59+
*/
60+
static DiscoveryIssueReporter deduplicating(DiscoveryIssueReporter delegate) {
61+
Preconditions.notNull(delegate, "delegate must not be null");
62+
Set<DiscoveryIssue> seen = new HashSet<>();
63+
return issue -> {
64+
boolean notSeen = seen.add(issue);
65+
if (notSeen) {
66+
delegate.reportIssue(issue);
67+
}
68+
};
69+
}
70+
5071
/**
5172
* Build the supplied {@link DiscoveryIssue.Builder Builder} and report the
5273
* resulting {@link DiscoveryIssue}.

junit-platform-engine/src/main/java/org/junit/platform/engine/support/discovery/EngineDiscoveryRequestResolver.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ private EngineDiscoveryRequestResolver(List<Function<InitializationContext<T>, S
6565

6666
/**
6767
* Resolve the supplied {@link EngineDiscoveryRequest} and collect the
68-
* results into the supplied {@link TestDescriptor}.
68+
* results into the supplied {@link TestDescriptor} while forwarding
69+
* encountered discovery issues to the {@link EngineDiscoveryRequest}'s
70+
* {@link org.junit.platform.engine.EngineDiscoveryListener}.
6971
*
7072
* <p>The algorithm works as follows:
7173
*
@@ -110,8 +112,35 @@ private EngineDiscoveryRequestResolver(List<Function<InitializationContext<T>, S
110112
public void resolve(EngineDiscoveryRequest request, T engineDescriptor) {
111113
Preconditions.notNull(request, "request must not be null");
112114
Preconditions.notNull(engineDescriptor, "engineDescriptor must not be null");
113-
DiscoveryIssueReporter issueReporter = DiscoveryIssueReporter.create(request.getDiscoveryListener(),
115+
DiscoveryIssueReporter issueReporter = DiscoveryIssueReporter.forwarding(request.getDiscoveryListener(),
114116
engineDescriptor.getUniqueId());
117+
resolve(request, engineDescriptor, issueReporter);
118+
}
119+
120+
/**
121+
* Resolve the supplied {@link EngineDiscoveryRequest} and collect the
122+
* results into the supplied {@link TestDescriptor} using the supplied
123+
* {@link DiscoveryIssueReporter} to report issues encountered during
124+
* resolution.
125+
*
126+
* <p>The algorithm works as described in
127+
* {@link #resolve(EngineDiscoveryRequest, TestDescriptor)}.
128+
*
129+
* @param request the request to be resolved; never {@code null}
130+
* @param engineDescriptor the engine's {@code TestDescriptor} to be used
131+
* for adding direct children
132+
* @param issueReporter the {@link DiscoveryIssueReporter} to report issues
133+
* encountered during resolution
134+
* @since 1.13
135+
* @see #resolve(EngineDiscoveryRequest, TestDescriptor)
136+
* @see SelectorResolver
137+
* @see TestDescriptor.Visitor
138+
*/
139+
@API(status = EXPERIMENTAL, since = "1.13")
140+
public void resolve(EngineDiscoveryRequest request, T engineDescriptor, DiscoveryIssueReporter issueReporter) {
141+
Preconditions.notNull(request, "request must not be null");
142+
Preconditions.notNull(engineDescriptor, "engineDescriptor must not be null");
143+
Preconditions.notNull(issueReporter, "issueReporter must not be null");
115144
InitializationContext<T> initializationContext = new DefaultInitializationContext<>(request, engineDescriptor,
116145
issueReporter);
117146
List<SelectorResolver> resolvers = instantiate(resolverCreators, initializationContext);

jupiter-tests/src/test/java/org/junit/jupiter/engine/discovery/DiscoveryTests.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,11 @@ static List<Named<LauncherDiscoveryRequest>> requestsForTestClassWithInvalidTest
197197
named("indirectly selected", request() //
198198
.selectors(selectPackage(InvalidTestMethodTestCase.class.getPackageName())) //
199199
.filters(
200-
includeClassNamePatterns(Pattern.quote(InvalidTestMethodTestCase.class.getName()))).build()) //
200+
includeClassNamePatterns(Pattern.quote(InvalidTestMethodTestCase.class.getName()))).build()), //
201+
named("subclasses", request() //
202+
.selectors(selectClass(InvalidTestMethodSubclass1TestCase.class),
203+
selectClass(InvalidTestMethodSubclass2TestCase.class)) //
204+
.build()) //
201205
);
202206
}
203207

@@ -277,4 +281,10 @@ private static int test() {
277281
}
278282
}
279283

284+
static class InvalidTestMethodSubclass1TestCase extends InvalidTestMethodTestCase {
285+
}
286+
287+
static class InvalidTestMethodSubclass2TestCase extends InvalidTestMethodTestCase {
288+
}
289+
280290
}

platform-tests/src/test/java/org/junit/platform/suite/engine/SuiteTestDescriptorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class SuiteTestDescriptorTests {
5050

5151
final ConfigurationParameters configurationParameters = new EmptyConfigurationParameters();
5252
final OutputDirectoryProvider outputDirectoryProvider = OutputDirectoryProviders.dummyOutputDirectoryProvider();
53-
final DiscoveryIssueReporter discoveryIssueReporter = DiscoveryIssueReporter.create(mock(), engineId);
53+
final DiscoveryIssueReporter discoveryIssueReporter = DiscoveryIssueReporter.forwarding(mock(), engineId);
5454
final SuiteTestDescriptor suite = new SuiteTestDescriptor(suiteId, TestSuite.class, configurationParameters,
5555
outputDirectoryProvider, discoveryIssueReporter);
5656

0 commit comments

Comments
 (0)