diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/SingleTestClass.java b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/SingleTestClass.java index 3744a817e..0321c48d4 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/SingleTestClass.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/SingleTestClass.java @@ -18,7 +18,6 @@ package org.apache.tools.ant.taskdefs.optional.junitlauncher; import org.junit.platform.engine.discovery.DiscoverySelectors; -import org.junit.platform.launcher.EngineFilter; import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; import javax.xml.stream.XMLStreamConstants; @@ -27,7 +26,6 @@ import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import java.util.Collections; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; import java.util.StringTokenizer; @@ -96,8 +94,8 @@ public class SingleTestClass extends TestDefinition implements NamedTest { } @Override - List createTestRequests() { - final LauncherDiscoveryRequestBuilder requestBuilder = LauncherDiscoveryRequestBuilder.request(); + void addDiscoverySelectors(final TestRequest testRequest) { + final LauncherDiscoveryRequestBuilder requestBuilder = testRequest.getDiscoveryRequest(); if (!this.hasMethodsSpecified()) { requestBuilder.selectors(DiscoverySelectors.selectClass(this.testClass)); } else { @@ -106,18 +104,9 @@ public class SingleTestClass extends TestDefinition implements NamedTest { requestBuilder.selectors(DiscoverySelectors.selectMethod(this.testClass, method)); } } - // add any engine filters - final String[] enginesToInclude = this.getIncludeEngines(); - if (enginesToInclude != null && enginesToInclude.length > 0) { - requestBuilder.filters(EngineFilter.includeEngines(enginesToInclude)); - } - final String[] enginesToExclude = this.getExcludeEngines(); - if (enginesToExclude != null && enginesToExclude.length > 0) { - requestBuilder.filters(EngineFilter.excludeEngines(enginesToExclude)); - } - return Collections.singletonList(new TestRequest(this, requestBuilder)); } + @Override protected void toForkedRepresentation(final JUnitLauncherTask task, final XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement(LD_XML_ELM_TEST); diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestClasses.java b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestClasses.java index cbba48497..1769d10ad 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestClasses.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestClasses.java @@ -20,6 +20,9 @@ package org.apache.tools.ant.taskdefs.optional.junitlauncher; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.resources.Resources; +import org.apache.tools.ant.types.resources.StringResource; +import org.junit.platform.engine.discovery.DiscoverySelectors; +import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; @@ -30,6 +33,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_CLASS_NAME; +import static org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_EXCLUDE_ENGINES; +import static org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_HALT_ON_FAILURE; +import static org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_INCLUDE_ENGINES; +import static org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_OUTPUT_DIRECTORY; +import static org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_TEST; import static org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_TEST_CLASSES; /** @@ -48,23 +57,22 @@ public class TestClasses extends TestDefinition { } @Override - List createTestRequests() { - final List tests = this.getTests(); + void addDiscoverySelectors(final TestRequest testRequest) { + final List tests = getTestClassNames(); if (tests.isEmpty()) { - return Collections.emptyList(); + return; } - final List requests = new ArrayList<>(); - for (final SingleTestClass test : tests) { - requests.addAll(test.createTestRequests()); + final LauncherDiscoveryRequestBuilder requestBuilder = testRequest.getDiscoveryRequest(); + for (final String test : tests) { + requestBuilder.selectors(DiscoverySelectors.selectClass(test)); } - return requests; } - private List getTests() { + private List getTestClassNames() { if (this.resources.isEmpty()) { return Collections.emptyList(); } - final List tests = new ArrayList<>(); + final List tests = new ArrayList<>(); for (final Resource resource : resources) { if (!resource.isExists()) { continue; @@ -75,83 +83,84 @@ public class TestClasses extends TestDefinition { continue; } final String className = name.substring(0, name.lastIndexOf('.')); - final BatchSourcedSingleTest test = new BatchSourcedSingleTest(className.replace(File.separatorChar, '.').replace('/', '.').replace('\\', '.')); - tests.add(test); + tests.add(className.replace(File.separatorChar, '.').replace('/', '.').replace('\\', '.')); } return tests; } - /** - * A {@link BatchSourcedSingleTest} is similar to a {@link SingleTestClass} except that - * some of the characteristics of the test (like whether to halt on failure) are borrowed - * from the {@link TestClasses batch} to which this test belongs to - */ - private final class BatchSourcedSingleTest extends SingleTestClass { - - private BatchSourcedSingleTest(final String testClassName) { - this.setName(testClassName); - } - - @Override - String getIfProperty() { - return TestClasses.this.getIfProperty(); - } - - @Override - String getUnlessProperty() { - return TestClasses.this.getUnlessProperty(); - } - - @Override - boolean isHaltOnFailure() { - return TestClasses.this.isHaltOnFailure(); - } - - @Override - String getFailureProperty() { - return TestClasses.this.getFailureProperty(); - } - - @Override - List getListeners() { - return TestClasses.this.getListeners(); - } - - @Override - String getOutputDir() { - return TestClasses.this.getOutputDir(); - } - - @Override - String[] getIncludeEngines() { - return TestClasses.this.getIncludeEngines(); - } - - @Override - String[] getExcludeEngines() { - return TestClasses.this.getExcludeEngines(); - } - } - @Override protected void toForkedRepresentation(final JUnitLauncherTask task, final XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement(LD_XML_ELM_TEST_CLASSES); - // write out as multiple SingleTestClass representations - for (final SingleTestClass singleTestClass : getTests()) { - singleTestClass.toForkedRepresentation(task, writer); + // write out each test class + for (final String test : getTestClassNames()) { + writer.writeStartElement(LD_XML_ELM_TEST); + writer.writeAttribute(LD_XML_ATTR_CLASS_NAME, test); + if (haltOnFailure != null) { + writer.writeAttribute(LD_XML_ATTR_HALT_ON_FAILURE, haltOnFailure.toString()); + } + if (outputDir != null) { + writer.writeAttribute(LD_XML_ATTR_OUTPUT_DIRECTORY, outputDir); + } + if (includeEngines != null) { + writer.writeAttribute(LD_XML_ATTR_INCLUDE_ENGINES, includeEngines); + } + if (excludeEngines != null) { + writer.writeAttribute(LD_XML_ATTR_EXCLUDE_ENGINES, excludeEngines); + } + // listeners for this test + if (listeners != null) { + for (final ListenerDefinition listenerDef : getListeners()) { + if (!listenerDef.shouldUse(task.getProject())) { + // not applicable + continue; + } + listenerDef.toForkedRepresentation(writer); + } + } + writer.writeEndElement(); } writer.writeEndElement(); } static List fromForkedRepresentation(final XMLStreamReader reader) throws XMLStreamException { reader.require(XMLStreamConstants.START_ELEMENT, null, LD_XML_ELM_TEST_CLASSES); - final List testDefinitions = new ArrayList<>(); + final TestClasses testDefinition = new TestClasses(); // read out as multiple SingleTestClass representations while (reader.nextTag() != XMLStreamConstants.END_ELEMENT) { reader.require(XMLStreamConstants.START_ELEMENT, null, Constants.LD_XML_ELM_TEST); - testDefinitions.add(SingleTestClass.fromForkedRepresentation(reader)); + final String testClassName = requireAttributeValue(reader, LD_XML_ATTR_CLASS_NAME); + testDefinition.add(new StringResource(testClassName + ".class")); + final String halt = reader.getAttributeValue(null, LD_XML_ATTR_HALT_ON_FAILURE); + if (halt != null) { + testDefinition.setHaltOnFailure(Boolean.parseBoolean(halt)); + } + final String outDir = reader.getAttributeValue(null, LD_XML_ATTR_OUTPUT_DIRECTORY); + if (outDir != null) { + testDefinition.setOutputDir(outDir); + } + final String includeEngs = reader.getAttributeValue(null, LD_XML_ATTR_INCLUDE_ENGINES); + if (includeEngs != null) { + testDefinition.setIncludeEngines(includeEngs); + } + final String excludeEngs = reader.getAttributeValue(null, LD_XML_ATTR_EXCLUDE_ENGINES); + if (excludeEngs != null) { + testDefinition.setExcludeEngines(excludeEngs); + } + while (reader.nextTag() != XMLStreamConstants.END_ELEMENT) { + reader.require(XMLStreamConstants.START_ELEMENT, null, Constants.LD_XML_ELM_LISTENER); + testDefinition.addConfiguredListener(ListenerDefinition.fromForkedRepresentation(reader)); + } + reader.require(XMLStreamConstants.END_ELEMENT, null, Constants.LD_XML_ELM_TEST); } reader.require(XMLStreamConstants.END_ELEMENT, null, LD_XML_ELM_TEST_CLASSES); - return testDefinitions; + return Collections.singletonList(testDefinition); + } + + private static String requireAttributeValue(final XMLStreamReader reader, final String attrName) throws XMLStreamException { + final String val = reader.getAttributeValue(null, attrName); + if (val != null) { + return val; + } + throw new XMLStreamException("Attribute " + attrName + " is missing at " + reader.getLocation()); } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestDefinition.java b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestDefinition.java index 9fe452f17..4a42b6aab 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestDefinition.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestDefinition.java @@ -20,6 +20,9 @@ package org.apache.tools.ant.taskdefs.optional.junitlauncher; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.PropertyHelper; +import org.junit.platform.engine.Filter; +import org.junit.platform.launcher.EngineFilter; +import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -107,7 +110,47 @@ abstract class TestDefinition { return this.forkDefinition; } - abstract List createTestRequests(); + /** + * Create and return the {@link TestRequest TestRequests} for this test definition. This + * typically involves creating the JUnit test discovery request(s) and applying the necessary + * discovery selectors, filters and other necessary constructs. + * + * @return Returns the test requests + */ + List createTestRequests() { + // create a TestRequest and add necessary selectors, filters to it + final LauncherDiscoveryRequestBuilder requestBuilder = LauncherDiscoveryRequestBuilder.request(); + final TestRequest request = new TestRequest(this, requestBuilder); + addDiscoverySelectors(request); + addFilters(request); + return Collections.singletonList(request); + } + + /** + * Add necessary {@link org.junit.platform.engine.DiscoverySelector JUnit discovery selectors} to + * the {@code testRequest} + * + * @param testRequest The test request + */ + abstract void addDiscoverySelectors(final TestRequest testRequest); + + /** + * Add necessary {@link Filter JUnit filters} to the {@code testRequest} + * + * @param testRequest The test request + */ + void addFilters(final TestRequest testRequest) { + final LauncherDiscoveryRequestBuilder requestBuilder = testRequest.getDiscoveryRequest(); + // add any engine filters + final String[] enginesToInclude = this.getIncludeEngines(); + if (enginesToInclude != null && enginesToInclude.length > 0) { + requestBuilder.filters(EngineFilter.includeEngines(enginesToInclude)); + } + final String[] enginesToExclude = this.getExcludeEngines(); + if (enginesToExclude != null && enginesToExclude.length > 0) { + requestBuilder.filters(EngineFilter.excludeEngines(enginesToExclude)); + } + } protected boolean shouldRun(final Project project) { final PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(project);