From 4752af0ce450d3b35b2e12b61bec5e8e3e3cea85 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Thu, 15 Jun 2017 20:00:35 +0200 Subject: [PATCH] Introduce TestDescriptor.mayRegisterTests() Fixes #508. --- .../docs/asciidoc/release-notes-5.0.0-M5.adoc | 5 ++++- .../descriptor/TestFactoryTestDescriptor.java | 2 +- .../TestTemplateTestDescriptor.java | 2 +- .../discovery/DiscoverySelectorResolver.java | 10 +++++----- .../junit/platform/engine/TestDescriptor.java | 20 +++++++++++++------ .../DemoHierarchicalContainerDescriptor.java | 2 +- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/documentation/src/docs/asciidoc/release-notes-5.0.0-M5.adoc b/documentation/src/docs/asciidoc/release-notes-5.0.0-M5.adoc index c99dd720068..5776def5839 100644 --- a/documentation/src/docs/asciidoc/release-notes-5.0.0-M5.adoc +++ b/documentation/src/docs/asciidoc/release-notes-5.0.0-M5.adoc @@ -65,7 +65,8 @@ is placed on the Java 9 module path. - `junit-platform-commons`: `ReflectionUtils.findAllClassesInClasspathRoot(Path, Predicate, Predicate)` * The `isLeaf()` method of the `org.junit.platform.engine.support.hierarchical.Node` interface has been removed. -* The default methods `prune()` and `pruneTree()` have been removed from `TestDescriptor`. +* The default methods `prune()`, `pruneTree()`, and `hasTests()` have been removed from + `TestDescriptor`. * The `DefaultLauncher` no longer prunes trees of `TestDescriptors` it receives from test engines. It's the responsibility of test engines to only return `TestDescriptors` they wish to execute. @@ -85,6 +86,8 @@ is placed on the Java 9 module path. * When a `TestEngine` is discovered via Java's `ServiceLoader` mechanism, an attempt will now be made to determine the location from which the engine class was loaded, and if the location URL is available, it will be logged at configuration-level. +* The `mayRegisterTests()` method may be used to signal that a `TestDescriptor` will + register dynamic tests during execution. [[release-notes-5.0.0-m5-junit-jupiter]] diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java index afb5280c176..7fee87c5803 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java @@ -55,7 +55,7 @@ public Type getType() { } @Override - public boolean hasTests() { + public boolean mayRegisterTests() { return true; } diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestTemplateTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestTemplateTestDescriptor.java index b08613da001..b427bc5da03 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestTemplateTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestTemplateTestDescriptor.java @@ -47,7 +47,7 @@ public Type getType() { } @Override - public boolean hasTests() { + public boolean mayRegisterTests() { return true; } diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/discovery/DiscoverySelectorResolver.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/discovery/DiscoverySelectorResolver.java index 23aeec7f9d4..005186ce3bf 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/discovery/DiscoverySelectorResolver.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/discovery/DiscoverySelectorResolver.java @@ -13,6 +13,7 @@ import static org.junit.platform.commons.meta.API.Usage.Experimental; import static org.junit.platform.commons.util.ReflectionUtils.findAllClassesInClasspathRoot; import static org.junit.platform.commons.util.ReflectionUtils.findAllClassesInPackage; +import static org.junit.platform.engine.TestDescriptor.containsTests; import static org.junit.platform.engine.support.filter.ClasspathScanningSupport.buildClassNamePredicate; import java.util.HashSet; @@ -67,12 +68,11 @@ public void resolveSelectors(EngineDiscoveryRequest request, TestDescriptor engi pruneTree(engineDescriptor); } - private void pruneTree(TestDescriptor engineDescriptor) { - engineDescriptor.accept(testDescriptor -> { - if (testDescriptor.isRoot() || testDescriptor.hasTests()) { - return; + private void pruneTree(TestDescriptor rootDescriptor) { + rootDescriptor.accept(testDescriptor -> { + if (!testDescriptor.isRoot() && !containsTests(testDescriptor)) { + testDescriptor.removeFromHierarchy(); } - testDescriptor.removeFromHierarchy(); }); } diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/TestDescriptor.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/TestDescriptor.java index a215a8dc2bc..8f197d38e6e 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/TestDescriptor.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/TestDescriptor.java @@ -185,14 +185,22 @@ default boolean isTest() { } /** - * Determine if this descriptor or any of its descendants describes a test. + * Determine if this descriptor may register dynamic tests during execution. * - *

The default implementation returns {@code true} if {@link #isTest()} - * returns {@code true} and otherwise recurses through this descriptor's - * {@linkplain #getChildren() children} to determine if they have tests. + *

The default implementation assumes tests are usually known during + * discovery and thus returns {@code false}. */ - default boolean hasTests() { - return isTest() || getChildren().stream().anyMatch(TestDescriptor::hasTests); + default boolean mayRegisterTests() { + return false; + } + + /** + * Determine if the supplied descriptor or any of its descendants contains + * any tests. + */ + static boolean containsTests(TestDescriptor testDescriptor) { + return testDescriptor.isTest() || testDescriptor.mayRegisterTests() + || testDescriptor.getChildren().stream().anyMatch(TestDescriptor::containsTests); } /** diff --git a/platform-tests/src/test/java/org/junit/platform/engine/support/hierarchical/DemoHierarchicalContainerDescriptor.java b/platform-tests/src/test/java/org/junit/platform/engine/support/hierarchical/DemoHierarchicalContainerDescriptor.java index c1f586445aa..7d78f85063b 100644 --- a/platform-tests/src/test/java/org/junit/platform/engine/support/hierarchical/DemoHierarchicalContainerDescriptor.java +++ b/platform-tests/src/test/java/org/junit/platform/engine/support/hierarchical/DemoHierarchicalContainerDescriptor.java @@ -47,7 +47,7 @@ public Type getType() { } @Override - public boolean hasTests() { + public boolean mayRegisterTests() { return true; }