Added support for collection arguments

This commit is contained in:
Erik C. Thauvin 2023-08-28 14:21:08 -07:00
parent b69faf34d6
commit f92ab27463
2 changed files with 235 additions and 1 deletions

View file

@ -98,12 +98,24 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
/** /**
* The list of groups you want to be excluded from this run. * The list of groups you want to be excluded from this run.
*
* @see #excludeGroups(Collection)
*/ */
public TestNgOperation excludeGroups(String... group) { public TestNgOperation excludeGroups(String... group) {
options.put("-excludegroups", String.join(",", group)); options.put("-excludegroups", String.join(",", group));
return this; return this;
} }
/**
* The list of groups you want to be excluded from this run.
*
* @see #excludeGroups(String...)
*/
public TestNgOperation excludeGroups(Collection<String> group) {
options.put("-excludegroups", String.join(",", group));
return this;
}
/** /**
* Part of the {@link #execute execute} operation, constructs the command list to use for building the process. * Part of the {@link #execute execute} operation, constructs the command list to use for building the process.
*/ */
@ -119,7 +131,7 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
options.put("d", Path.of(project.buildDirectory().getPath(), "test-output").toString()); options.put("d", Path.of(project.buildDirectory().getPath(), "test-output").toString());
} }
List<String> args = new ArrayList<>(); final List<String> args = new ArrayList<>();
args.add(javaTool()); args.add(javaTool());
args.add("-cp"); args.add("-cp");
@ -197,12 +209,26 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
* The list of groups you want to run. * The list of groups you want to run.
* *
* <p>For example: {@code "windows", "linux", "regression}</p> * <p>For example: {@code "windows", "linux", "regression}</p>
*
* @see #groups(Collection)
*/ */
public TestNgOperation groups(String... group) { public TestNgOperation groups(String... group) {
options.put("-groups", String.join(",", group)); options.put("-groups", String.join(",", group));
return this; return this;
} }
/**
* The list of groups you want to run.
*
* <p>For example: {@code "windows", "linux", "regression}</p>
*
* @see #groups(String...)
*/
public TestNgOperation groups(Collection<String> group) {
options.put("-groups", String.join(",", group));
return this;
}
/** /**
* Ignore missed test names given by {@link #testNames(String...) testNames} and continue to run existing tests, * Ignore missed test names given by {@link #testNames(String...) testNames} and continue to run existing tests,
* if any. * if any.
@ -237,12 +263,25 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
/** /**
* The list of {@code .class} files or list of class names implementing {@code ITestListener} or * The list of {@code .class} files or list of class names implementing {@code ITestListener} or
* {@code ISuiteListener} * {@code ISuiteListener}
*
* @see #listener(Collection)
*/ */
public TestNgOperation listener(String... listener) { public TestNgOperation listener(String... listener) {
options.put("-listener", String.join(",", listener)); options.put("-listener", String.join(",", listener));
return this; return this;
} }
/**
* The list of {@code .class} files or list of class names implementing {@code ITestListener} or
* {@code ISuiteListener}
*
* @see #listener(String...)
*/
public TestNgOperation listener(Collection<String> listener) {
options.put("-listener", String.join(",", listener));
return this;
}
/** /**
* Set the Level of verbosity. * Set the Level of verbosity.
* *
@ -257,22 +296,50 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
* Specifies the list of {@code .class} files or class names implementing {@code IMethodSelector}. * Specifies the list of {@code .class} files or class names implementing {@code IMethodSelector}.
* *
* <p>For example: {@code "com.example.Selector1:3", "com.example.Selector2:2"}</p> * <p>For example: {@code "com.example.Selector1:3", "com.example.Selector2:2"}</p>
*
* @see #methodSelectors(Collection)
*/ */
public TestNgOperation methodSelectors(String... selector) { public TestNgOperation methodSelectors(String... selector) {
options.put("-methodselectors", String.join(",", selector)); options.put("-methodselectors", String.join(",", selector));
return this; return this;
} }
/**
* Specifies the list of {@code .class} files or class names implementing {@code IMethodSelector}.
*
* <p>For example: {@code "com.example.Selector1:3", "com.example.Selector2:2"}</p>
*
* @see #methodSelectors(String...)
*/
public TestNgOperation methodSelectors(Collection<String> selector) {
options.put("-methodselectors", String.join(",", selector));
return this;
}
/** /**
* Lets you specify individual methods to run. * Lets you specify individual methods to run.
* *
* <p>For example: {@code "com.example.Foo.f1", "com.example.Bar.f2"}</p> * <p>For example: {@code "com.example.Foo.f1", "com.example.Bar.f2"}</p>
*
* @see #methods(Collection)
*/ */
public TestNgOperation methods(String... method) { public TestNgOperation methods(String... method) {
options.put("-methods", String.join(",", method)); options.put("-methods", String.join(",", method));
return this; return this;
} }
/**
* Lets you specify individual methods to run.
*
* <p>For example: {@code "com.example.Foo.f1", "com.example.Bar.f2"}</p>
*
* @see #methods(String...)
*/
public TestNgOperation methods(Collection<String> method) {
options.put("-methods", String.join(",", method));
return this;
}
/** /**
* Mixed mode autodetects the type of current test and run it with appropriate runner. * Mixed mode autodetects the type of current test and run it with appropriate runner.
* *
@ -285,33 +352,74 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
/** /**
* The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}. * The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}.
*
* @see #objectFactory(Collection)
*/ */
public TestNgOperation objectFactory(String... factory) { public TestNgOperation objectFactory(String... factory) {
options.put("-objectfactory", String.join(",", factory)); options.put("-objectfactory", String.join(",", factory));
return this; return this;
} }
/**
* The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}.
*
* @see #objectFactory(String...)
*/
public TestNgOperation objectFactory(Collection<String> factory) {
options.put("-objectfactory", String.join(",", factory));
return this;
}
/** /**
* The list of fully qualified class names of listeners that should be skipped from being wired in via * The list of fully qualified class names of listeners that should be skipped from being wired in via
* Service Loaders. * Service Loaders.
*
* @see #overrideIncludedMethods(Collection)
*/ */
public TestNgOperation overrideIncludedMethods(String... method) { public TestNgOperation overrideIncludedMethods(String... method) {
options.put("-overrideincludedmethods", String.join(",", method)); options.put("-overrideincludedmethods", String.join(",", method));
return this; return this;
} }
/**
* The list of fully qualified class names of listeners that should be skipped from being wired in via
* Service Loaders.
*
* @see #overrideIncludedMethods(String...)
*/
public TestNgOperation overrideIncludedMethods(Collection<String> method) {
options.put("-overrideincludedmethods", String.join(",", method));
return this;
}
/** /**
* The list of packages to include in this test. * The list of packages to include in this test.
* If the package name ends with .* then subpackages are included too. * If the package name ends with .* then subpackages are included too.
* Required if no {@link #suites(String... suites)} specified. * Required if no {@link #suites(String... suites)} specified.
* *
* <p>For example: {@code "com.example", "test.sample.*"}</p> * <p>For example: {@code "com.example", "test.sample.*"}</p>
*
* @see #packages(Collection)
*/ */
public TestNgOperation packages(String... name) { public TestNgOperation packages(String... name) {
packages.addAll(Arrays.stream(name).toList()); packages.addAll(Arrays.stream(name).toList());
return this; return this;
} }
/**
* The list of packages to include in this test.
* If the package name ends with .* then subpackages are included too.
* Required if no {@link #suites(String... suites)} specified.
*
* <p>For example: {@code "com.example", "test.sample.*"}</p>
*
* @see #packages(String...)
*/
public TestNgOperation packages(Collection<String> name) {
packages.addAll(name);
return this;
}
/** /**
* If specified, sets the default mechanism used to determine how to use parallel threads when running tests. * If specified, sets the default mechanism used to determine how to use parallel threads when running tests.
* If not set, default mechanism is not to use parallel threads at all. * If not set, default mechanism is not to use parallel threads at all.
@ -354,21 +462,48 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
* The directories where your javadoc annotated test sources are. This option is only necessary * The directories where your javadoc annotated test sources are. This option is only necessary
* if you are using javadoc type annotations. (e.g. {@code "src/test"} or * if you are using javadoc type annotations. (e.g. {@code "src/test"} or
* {@code "src/test/org/testng/eclipse-plugin", "src/test/org/testng/testng"}). * {@code "src/test/org/testng/eclipse-plugin", "src/test/org/testng/testng"}).
*
* @see #sourceDir(String...)
*/ */
public TestNgOperation sourceDir(String... directory) { public TestNgOperation sourceDir(String... directory) {
options.put("-sourcedir", String.join(";", directory)); options.put("-sourcedir", String.join(";", directory));
return this; return this;
} }
/**
* The directories where your javadoc annotated test sources are. This option is only necessary
* if you are using javadoc type annotations. (e.g. {@code "src/test"} or
* {@code "src/test/org/testng/eclipse-plugin", "src/test/org/testng/testng"}).
*
* @see #sourceDir(String...)
*/
public TestNgOperation sourceDir(Collection<String> directory) {
options.put("-sourcedir", String.join(";", directory));
return this;
}
/** /**
* Specifies the List of fully qualified class names of listeners that should be skipped from being wired in via * Specifies the List of fully qualified class names of listeners that should be skipped from being wired in via
* Service Loaders. * Service Loaders.
*
* @see #spiListenersToSkip(Collection)
*/ */
public TestNgOperation spiListenersToSkip(String... listenerToSkip) { public TestNgOperation spiListenersToSkip(String... listenerToSkip) {
options.put("-spilistenerstoskip", String.join(",", listenerToSkip)); options.put("-spilistenerstoskip", String.join(",", listenerToSkip));
return this; return this;
} }
/**
* Specifies the List of fully qualified class names of listeners that should be skipped from being wired in via
* Service Loaders.
*
* @see #spiListenersToSkip(String...)
*/
public TestNgOperation spiListenersToSkip(Collection<String> listenerToSkip) {
options.put("-spilistenerstoskip", String.join(",", listenerToSkip));
return this;
}
/** /**
* This specifies the default name of the test suite, if not specified in the suite definition file or source code. * This specifies the default name of the test suite, if not specified in the suite definition file or source code.
* This option is ignored if the {@code suite.xml} file or the source code specifies a different suite name. * This option is ignored if the {@code suite.xml} file or the source code specifies a different suite name.
@ -391,12 +526,26 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
* Specifies the suites to run. * Specifies the suites to run.
* *
* <p>For example: {@code "testng.xml", "testng2.xml"}</p> * <p>For example: {@code "testng.xml", "testng2.xml"}</p>
*
* @see #suites(Collection)
*/ */
public TestNgOperation suites(String... suite) { public TestNgOperation suites(String... suite) {
suites.addAll(Arrays.stream(suite).toList()); suites.addAll(Arrays.stream(suite).toList());
return this; return this;
} }
/**
* Specifies the suites to run.
*
* <p>For example: {@code "testng.xml", "testng2.xml"}</p>
*
* @see #suites(String...)
*/
public TestNgOperation suites(Collection<String> suite) {
suites.addAll(suite);
return this;
}
/** /**
* Create a test file and delete it on exit. * Create a test file and delete it on exit.
*/ */
@ -410,20 +559,46 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
* Specifies the list of class files. * Specifies the list of class files.
* *
* <p>For example: {@code "org.foo.Test1","org.foo.test2"}</p> * <p>For example: {@code "org.foo.Test1","org.foo.test2"}</p>
*
* @see #testClass(Collection)
*/ */
public TestNgOperation testClass(String... aClass) { public TestNgOperation testClass(String... aClass) {
options.put("-testclass", String.join(",", aClass)); options.put("-testclass", String.join(",", aClass));
return this; return this;
} }
/**
* Specifies the list of class files.
*
* <p>For example: {@code "org.foo.Test1","org.foo.test2"}</p>
*
* @see #testClass(String...)
*/
public TestNgOperation testClass(Collection<String> aClass) {
options.put("-testclass", String.join(",", aClass));
return this;
}
/** /**
* Specifies the classpath entries used to run tests. * Specifies the classpath entries used to run tests.
*
* @see #testClasspath(String...)
*/ */
public TestNgOperation testClasspath(String... entry) { public TestNgOperation testClasspath(String... entry) {
testClasspath.addAll(Arrays.stream(entry).toList()); testClasspath.addAll(Arrays.stream(entry).toList());
return this; return this;
} }
/**
* Specifies the classpath entries used to run tests.
*
* @see #testClasspath(String...)
*/
public TestNgOperation testClasspath(Collection<String> entry) {
testClasspath.addAll(entry);
return this;
}
/** /**
* Specifies a jar file that contains test classes. If a {@code testng.xml} file is found at the root of that * Specifies a jar file that contains test classes. If a {@code testng.xml} file is found at the root of that
* jar file, it will be used, otherwise, all the test classes found in this jar file will be considered test * jar file, it will be used, otherwise, all the test classes found in this jar file will be considered test
@ -445,12 +620,24 @@ public class TestNgOperation extends AbstractProcessOperation<TestNgOperation> {
/** /**
* Only tests defined in a {@code <test>} tag matching one of these names will be run. * Only tests defined in a {@code <test>} tag matching one of these names will be run.
*
* @see #testNames(Collection)
*/ */
public TestNgOperation testNames(String... name) { public TestNgOperation testNames(String... name) {
options.put("-testnames", Arrays.stream(name).map(s -> '"' + s + '"').collect(Collectors.joining(","))); options.put("-testnames", Arrays.stream(name).map(s -> '"' + s + '"').collect(Collectors.joining(",")));
return this; return this;
} }
/**
* Only tests defined in a {@code <test>} tag matching one of these names will be run.
*
* @see #testName(String)
*/
public TestNgOperation testNames(Collection<String> name) {
options.put("-testnames", name.stream().map(s -> '"' + s + '"').collect(Collectors.joining(",")));
return this;
}
/** /**
* Specifies the factory used to create tests. * Specifies the factory used to create tests.
*/ */

View file

@ -20,6 +20,8 @@ import org.junit.jupiter.api.Test;
import rife.bld.Project; // NOPMD import rife.bld.Project; // NOPMD
import rife.bld.operations.exceptions.ExitStatusException; import rife.bld.operations.exceptions.ExitStatusException;
import java.util.List;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
/** /**
@ -46,6 +48,10 @@ class TestNgOperationTest {
void testClass() { void testClass() {
var op = new TestNgOperation().testClass(FOO, BAR); var op = new TestNgOperation().testClass(FOO, BAR);
assertThat(op.options.get(TestNgOperation.TEST_CLASS_ARG)).isEqualTo(String.format("%s,%s", FOO, BAR)); assertThat(op.options.get(TestNgOperation.TEST_CLASS_ARG)).isEqualTo(String.format("%s,%s", FOO, BAR));
new TestNgOperation().testClass(List.of(FOO, BAR));
assertThat(op.options.get(TestNgOperation.TEST_CLASS_ARG)).as("as list")
.isEqualTo(String.format("%s,%s", FOO, BAR));
} }
@Test @Test
@ -70,6 +76,9 @@ class TestNgOperationTest {
void testExcludeGroups() { void testExcludeGroups() {
var op = new TestNgOperation().excludeGroups(FOO, BAR); var op = new TestNgOperation().excludeGroups(FOO, BAR);
assertThat(op.options.get("-excludegroups")).isEqualTo(String.format("%s,%s", FOO, BAR)); assertThat(op.options.get("-excludegroups")).isEqualTo(String.format("%s,%s", FOO, BAR));
op = new TestNgOperation().excludeGroups(List.of(FOO, BAR));
assertThat(op.options.get("-excludegroups")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR));
} }
@Test @Test
@ -113,6 +122,14 @@ class TestNgOperationTest {
.log(2) .log(2)
.execute()) .execute())
.as("with run classpath").doesNotThrowAnyException(); .as("with run classpath").doesNotThrowAnyException();
assertThatCode(() ->
new TestNgOperation().fromProject(new Project())
.suites("src/test/resources/testng3.xml")
.testClasspath(List.of("lib/test/*", "build/main", "build/test"))
.log(2)
.execute())
.as("with run classpath as list").doesNotThrowAnyException();
} }
@Test @Test
@ -185,18 +202,27 @@ class TestNgOperationTest {
void testListener() { void testListener() {
var ops = new TestNgOperation().listener(FOO, BAR); var ops = new TestNgOperation().listener(FOO, BAR);
assertThat(ops.options.get("-listener")).isEqualTo(String.format("%s,%s", FOO, BAR)); assertThat(ops.options.get("-listener")).isEqualTo(String.format("%s,%s", FOO, BAR));
ops = new TestNgOperation().listener(List.of(FOO, BAR));
assertThat(ops.options.get("-listener")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR));
} }
@Test @Test
void testMethodDetectors() { void testMethodDetectors() {
var op = new TestNgOperation().methodSelectors(FOO, BAR); var op = new TestNgOperation().methodSelectors(FOO, BAR);
assertThat(op.options.get("-methodselectors")).isEqualTo(String.format("%s,%s", FOO, BAR)); assertThat(op.options.get("-methodselectors")).isEqualTo(String.format("%s,%s", FOO, BAR));
op = new TestNgOperation().methodSelectors(List.of(FOO, BAR));
assertThat(op.options.get("-methodselectors")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR));
} }
@Test @Test
void testMethods() { void testMethods() {
var op = new TestNgOperation().methods(FOO, BAR); var op = new TestNgOperation().methods(FOO, BAR);
assertThat(op.options.get("-methods")).isEqualTo(String.format("%s,%s", FOO, BAR)); assertThat(op.options.get("-methods")).isEqualTo(String.format("%s,%s", FOO, BAR));
new TestNgOperation().methods(List.of(FOO, BAR));
assertThat(op.options.get("-methods")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR));
} }
@Test @Test
@ -218,24 +244,36 @@ class TestNgOperationTest {
void testNames() { void testNames() {
var ops = new TestNgOperation().testNames(FOO, BAR); var ops = new TestNgOperation().testNames(FOO, BAR);
assertThat(ops.options.get("-testnames")).isEqualTo(String.format("\"%s\",\"%s\"", FOO, BAR)); assertThat(ops.options.get("-testnames")).isEqualTo(String.format("\"%s\",\"%s\"", FOO, BAR));
new TestNgOperation().testNames(List.of(FOO, BAR));
assertThat(ops.options.get("-testnames")).as("as list").isEqualTo(String.format("\"%s\",\"%s\"", FOO, BAR));
} }
@Test @Test
void testObjectFactory() { void testObjectFactory() {
var ops = new TestNgOperation().objectFactory(FOO, BAR); var ops = new TestNgOperation().objectFactory(FOO, BAR);
assertThat(ops.options.get("-objectfactory")).isEqualTo(String.format("%s,%s", FOO, BAR)); assertThat(ops.options.get("-objectfactory")).isEqualTo(String.format("%s,%s", FOO, BAR));
ops = new TestNgOperation().objectFactory(List.of(FOO, BAR));
assertThat(ops.options.get("-objectfactory")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR));
} }
@Test @Test
void testOverrideIncludedMethods() { void testOverrideIncludedMethods() {
var ops = new TestNgOperation().overrideIncludedMethods(FOO, BAR); var ops = new TestNgOperation().overrideIncludedMethods(FOO, BAR);
assertThat(ops.options.get("-overrideincludedmethods")).isEqualTo(String.format("%s,%s", FOO, BAR)); assertThat(ops.options.get("-overrideincludedmethods")).isEqualTo(String.format("%s,%s", FOO, BAR));
ops = new TestNgOperation().overrideIncludedMethods(List.of(FOO, BAR));
assertThat(ops.options.get("-overrideincludedmethods")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR));
} }
@Test @Test
void testPackages() { void testPackages() {
var op = new TestNgOperation().packages(FOO, BAR); var op = new TestNgOperation().packages(FOO, BAR);
assertThat(op.packages).contains(FOO).contains(BAR); assertThat(op.packages).contains(FOO).contains(BAR);
op = new TestNgOperation().packages(List.of(FOO, BAR));
assertThat(op.packages).as("as list").contains(FOO).contains(BAR);
} }
@Test @Test
@ -281,12 +319,18 @@ class TestNgOperationTest {
void testSourceDir() { void testSourceDir() {
var op = new TestNgOperation().sourceDir(FOO, BAR); var op = new TestNgOperation().sourceDir(FOO, BAR);
assertThat(op.options.get("-sourcedir")).isEqualTo(String.format("%s;%s", FOO, BAR)); assertThat(op.options.get("-sourcedir")).isEqualTo(String.format("%s;%s", FOO, BAR));
op = new TestNgOperation().sourceDir(List.of(FOO, BAR));
assertThat(op.options.get("-sourcedir")).as("as list").isEqualTo(String.format("%s;%s", FOO, BAR));
} }
@Test @Test
void testSpiListenersToSkip() { void testSpiListenersToSkip() {
var ops = new TestNgOperation().spiListenersToSkip(FOO, BAR); var ops = new TestNgOperation().spiListenersToSkip(FOO, BAR);
assertThat(ops.options.get("-spilistenerstoskip")).isEqualTo(String.format("%s,%s", FOO, BAR)); assertThat(ops.options.get("-spilistenerstoskip")).isEqualTo(String.format("%s,%s", FOO, BAR));
ops = new TestNgOperation().spiListenersToSkip(List.of(FOO, BAR));
assertThat(ops.options.get("-spilistenerstoskip")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR));
} }
@Test @Test
@ -305,6 +349,9 @@ class TestNgOperationTest {
void testSuites() { void testSuites() {
var op = new TestNgOperation().suites(FOO, BAR); var op = new TestNgOperation().suites(FOO, BAR);
assertThat(op.suites).contains(FOO).contains(BAR); assertThat(op.suites).contains(FOO).contains(BAR);
op = new TestNgOperation().suites(List.of(FOO, BAR));
assertThat(op.suites).as("as list").contains(FOO).contains(BAR);
} }
@Test @Test