diff --git a/.github/workflows/bld.yml b/.github/workflows/bld.yml index c5434f3..d55711f 100644 --- a/.github/workflows/bld.yml +++ b/.github/workflows/bld.yml @@ -4,11 +4,13 @@ on: [ push, pull_request, workflow_dispatch ] jobs: build-bld-project: - runs-on: ubuntu-latest - strategy: matrix: - java-version: [ 17, 21, 22 ] + java-version: [ 17, 21, 24 ] + kotlin-version: [ 1.9.25, 2.0.21, 2.1.20 ] + os: [ ubuntu-latest, windows-latest, macos-latest ] + + runs-on: ${{ matrix.os }} steps: - name: Checkout source repository @@ -22,8 +24,16 @@ jobs: distribution: "zulu" java-version: ${{ matrix.java-version }} + - name: Download dependencies [examples] + working-directory: examples + run: ./bld download + + - name: Run tests with JaCoCo [examples] + working-directory: examples + run: ./bld compile jacoco + - name: Download dependencies run: ./bld download - name: Run tests - run: ./bld compile test + run: ./bld compile test \ No newline at end of file diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index bf43624..508f6a5 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -47,11 +47,11 @@ jobs: uses: actions/configure-pages@v3 - name: Upload artifact - uses: actions/upload-pages-artifact@v1 + uses: actions/upload-pages-artifact@v3 with: # Upload generated Javadocs repository path: "build/javadoc/" - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v1 + uses: actions/deploy-pages@v4 diff --git a/.idea/bld.xml b/.idea/bld.xml new file mode 100644 index 0000000..6600cee --- /dev/null +++ b/.idea/bld.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/copyright/Apache_License.xml b/.idea/copyright/Apache_License.xml index ade80da..4446c15 100644 --- a/.idea/copyright/Apache_License.xml +++ b/.idea/copyright/Apache_License.xml @@ -1,6 +1,6 @@ - - + \ No newline at end of file diff --git a/.idea/icon.svg b/.idea/icon.svg new file mode 100644 index 0000000..81220b4 --- /dev/null +++ b/.idea/icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/.idea/libraries/bld.xml b/.idea/libraries/bld.xml index 867d049..a203de8 100644 --- a/.idea/libraries/bld.xml +++ b/.idea/libraries/bld.xml @@ -2,12 +2,12 @@ - + - + diff --git a/.idea/libraries/compile.xml b/.idea/libraries/compile.xml index 9bd86aa..99cc0c0 100644 --- a/.idea/libraries/compile.xml +++ b/.idea/libraries/compile.xml @@ -7,7 +7,7 @@ - - + + \ No newline at end of file diff --git a/.idea/libraries/runtime.xml b/.idea/libraries/runtime.xml index 2ae5c4b..d4069f2 100644 --- a/.idea/libraries/runtime.xml +++ b/.idea/libraries/runtime.xml @@ -8,7 +8,7 @@ - - + + \ No newline at end of file diff --git a/.idea/libraries/test.xml b/.idea/libraries/test.xml index b80486a..57ed5ef 100644 --- a/.idea/libraries/test.xml +++ b/.idea/libraries/test.xml @@ -8,7 +8,7 @@ - - + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 5b2667b..ba429d0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.bld/dist/bld-2.0.1.jar", + "${HOME}/.bld/dist/bld-2.2.1.jar", "lib/**/*.jar" ] } diff --git a/README.md b/README.md index 60344f8..e44b64e 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,20 @@ [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) -[![bld](https://img.shields.io/badge/2.0.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) +[![bld](https://img.shields.io/badge/2.2.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) [![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/bld-testng/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/bld-testng) [![Snapshot](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/snapshots/com/uwyn/rife2/bld-testng/maven-metadata.xml?label=snapshot)](https://repo.rife2.com/#/snapshots/com/uwyn/rife2/bld-testng) [![GitHub CI](https://github.com/rife2/bld-testng/actions/workflows/bld.yml/badge.svg)](https://github.com/rife2/bld-testng/actions/workflows/bld.yml) -To install, please refer to the [extensions documentation](https://github.com/rife2/bld/wiki/Extensions). +To install the latest version, add the following to the `lib/bld/bld-wrapper.properties` file: + +```properties +bld.extension-testng=com.uwyn.rife2:bld-testng +``` + +For more information, please refer to the [extensions](https://github.com/rife2/bld/wiki/Extensions) documentation. + +## Test with TestNG To run the tests with TestNG, add the following to your build file: @@ -34,5 +42,5 @@ Don't forget to add a TestNG `test` dependency to your build file, as it is not ```java repositories = List.of(MAVEN_CENTRAL); -scope(test).include(dependency("org.testng", "testng", version(7, 10, 2))); +scope(test).include(dependency("org.testng", "testng", version(7, 11, 0))); ``` diff --git a/config/pmd.xml b/config/pmd.xml index 3d3203c..2641880 100644 --- a/config/pmd.xml +++ b/config/pmd.xml @@ -7,9 +7,9 @@ - - + + diff --git a/examples/.idea/bld.xml b/examples/.idea/bld.xml new file mode 100644 index 0000000..6600cee --- /dev/null +++ b/examples/.idea/bld.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/.idea/libraries/bld.xml b/examples/.idea/libraries/bld.xml index 867d049..a203de8 100644 --- a/examples/.idea/libraries/bld.xml +++ b/examples/.idea/libraries/bld.xml @@ -2,12 +2,12 @@ - + - + diff --git a/examples/.idea/libraries/compile.xml b/examples/.idea/libraries/compile.xml index 9bd86aa..99cc0c0 100644 --- a/examples/.idea/libraries/compile.xml +++ b/examples/.idea/libraries/compile.xml @@ -7,7 +7,7 @@ - - + + \ No newline at end of file diff --git a/examples/.idea/libraries/runtime.xml b/examples/.idea/libraries/runtime.xml index 2ae5c4b..d4069f2 100644 --- a/examples/.idea/libraries/runtime.xml +++ b/examples/.idea/libraries/runtime.xml @@ -8,7 +8,7 @@ - - + + \ No newline at end of file diff --git a/examples/.idea/libraries/test.xml b/examples/.idea/libraries/test.xml index b80486a..57ed5ef 100644 --- a/examples/.idea/libraries/test.xml +++ b/examples/.idea/libraries/test.xml @@ -8,7 +8,7 @@ - - + + \ No newline at end of file diff --git a/examples/.vscode/settings.json b/examples/.vscode/settings.json index 2104130..3005cd9 100644 --- a/examples/.vscode/settings.json +++ b/examples/.vscode/settings.json @@ -10,7 +10,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.bld/dist/bld-2.0.1.jar", + "${HOME}/.bld/dist/bld-2.2.1.jar", "lib/**/*.jar" ] } diff --git a/examples/lib/bld/bld-wrapper.jar b/examples/lib/bld/bld-wrapper.jar index cea3974..88faac2 100644 Binary files a/examples/lib/bld/bld-wrapper.jar and b/examples/lib/bld/bld-wrapper.jar differ diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index f79dc2b..85fd25e 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,8 +1,8 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true bld.downloadLocation= -bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.7 -bld.extension-testng=com.uwyn.rife2:bld-testng:0.9.9 +bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.10-SNAPSHOT +bld.extension-testng=com.uwyn.rife2:bld-testng:1.0.3-SNAPSHOT bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.sourceDirectories= -bld.version=2.0.1 +bld.version=2.2.1 diff --git a/examples/src/bld/java/com/example/ExamplesBuild.java b/examples/src/bld/java/com/example/ExamplesBuild.java index 6827d0e..9bd0bea 100644 --- a/examples/src/bld/java/com/example/ExamplesBuild.java +++ b/examples/src/bld/java/com/example/ExamplesBuild.java @@ -6,7 +6,6 @@ import rife.bld.extension.JacocoReportOperation; import rife.bld.extension.TestNgOperation; import rife.bld.operations.TestOperation; -import java.io.IOException; import java.util.List; import java.util.logging.ConsoleHandler; import java.util.logging.Level; @@ -17,7 +16,7 @@ import static rife.bld.dependencies.Scope.test; /** * Example build. - * + * *
{@code
  * ./bld compile test
  * ./bld compile jacoco
@@ -36,7 +35,7 @@ public class ExamplesBuild extends BaseProject {
 
         repositories = List.of(MAVEN_CENTRAL);
 
-        scope(test).include(dependency("org.testng", "testng", version(7, 10, 2)));
+        scope(test).include(dependency("org.testng", "testng", version(7, 11, 0)));
     }
 
     public static void main(String[] args) {
diff --git a/lib/bld/bld-wrapper.jar b/lib/bld/bld-wrapper.jar
index ee23353..97c0a4b 100644
Binary files a/lib/bld/bld-wrapper.jar and b/lib/bld/bld-wrapper.jar differ
diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties
index 79b2f59..c5da09f 100644
--- a/lib/bld/bld-wrapper.properties
+++ b/lib/bld/bld-wrapper.properties
@@ -1,8 +1,8 @@
 bld.downloadExtensionJavadoc=false
 bld.downloadExtensionSources=true
 bld.downloadLocation=
-bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.2
-bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.1.4
+bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.4
+bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.2.1
 bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
 bld.sourceDirectories=
-bld.version=2.0.1
+bld.version=2.2.1
diff --git a/src/bld/java/rife/bld/extension/TestNgOperationBuild.java b/src/bld/java/rife/bld/extension/TestNgOperationBuild.java
index 4c85037..88f713c 100644
--- a/src/bld/java/rife/bld/extension/TestNgOperationBuild.java
+++ b/src/bld/java/rife/bld/extension/TestNgOperationBuild.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023-2024 the original author or authors.
+ * Copyright 2023-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,10 +24,7 @@ import rife.bld.publish.PublishScm;
 
 import java.util.List;
 
-import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
-import static rife.bld.dependencies.Repository.MAVEN_LOCAL;
-import static rife.bld.dependencies.Repository.RIFE2_RELEASES;
-import static rife.bld.dependencies.Repository.RIFE2_SNAPSHOTS;
+import static rife.bld.dependencies.Repository.*;
 import static rife.bld.dependencies.Scope.compile;
 import static rife.bld.dependencies.Scope.test;
 import static rife.bld.operations.JavadocOptions.DocLinkOption.NO_MISSING;
@@ -36,22 +33,23 @@ public class TestNgOperationBuild extends Project {
     public TestNgOperationBuild() {
         pkg = "rife.bld.extension";
         name = "bld-testng";
-        version = version(0, 9, 9);
+        version = version(1, 0, 3, "SNAPSHOT");
 
         javaRelease = 17;
 
         downloadSources = true;
         autoDownloadPurge = true;
+        
         repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES, RIFE2_SNAPSHOTS);
 
         scope(compile)
-                .include(dependency("com.uwyn.rife2", "bld", version(2, 0, 1)));
+                .include(dependency("com.uwyn.rife2", "bld", version(2, 2, 1)));
 
         scope(test)
-                .include(dependency("org.testng", "testng", version(7, 10, 2)))
-                .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 3)))
-                .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 3)))
-                .include(dependency("org.assertj", "assertj-core", version(3, 26, 3)));
+                .include(dependency("org.testng", "testng", version(7, 11, 0)))
+                .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 12, 1)))
+                .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 12, 1)))
+                .include(dependency("org.assertj", "assertj-core", version(3, 27, 3)));
 
         javadocOperation()
                 .javadocOptions()
@@ -62,28 +60,26 @@ public class TestNgOperationBuild extends Project {
 
         publishOperation()
                 .repository(version.isSnapshot() ? repository("rife2-snapshot") : repository("rife2"))
+                .repository(repository("github"))
                 .info()
                 .groupId("com.uwyn.rife2")
                 .artifactId("bld-testng")
                 .description("bld Extension to execute tests with TestNG")
                 .url("https://github.com/rife2/bld-testng")
-                .developer(
-                        new PublishDeveloper()
-                                .id("ethauvin")
-                                .name("Erik C. Thauvin")
-                                .email("erik@thauvin.net")
-                                .url("https://erik.thauvin.net/")
+                .developer(new PublishDeveloper()
+                        .id("ethauvin")
+                        .name("Erik C. Thauvin")
+                        .email("erik@thauvin.net")
+                        .url("https://erik.thauvin.net/")
                 )
-                .license(
-                        new PublishLicense()
-                                .name("The Apache License, Version 2.0")
-                                .url("https://www.apache.org/licenses/LICENSE-2.0.txt")
+                .license(new PublishLicense()
+                        .name("The Apache License, Version 2.0")
+                        .url("https://www.apache.org/licenses/LICENSE-2.0.txt")
                 )
-                .scm(
-                        new PublishScm()
-                                .connection("scm:git:https://github.com/rife2/bld-testng.git")
-                                .developerConnection("scm:git:git@github.com:rife2/bld-testng.git")
-                                .url("https://github.com/rife2/bld-testng")
+                .scm(new PublishScm()
+                        .connection("scm:git:https://github.com/rife2/bld-testng.git")
+                        .developerConnection("scm:git:git@github.com:rife2/bld-testng.git")
+                        .url("https://github.com/rife2/bld-testng")
                 )
                 .signKey(property("sign.key"))
                 .signPassphrase(property("sign.passphrase"));
@@ -104,10 +100,13 @@ public class TestNgOperationBuild extends Project {
 
     @Override
     public void test() throws Exception {
-        new ExecOperation()
-                .fromProject(this)
-                .command("scripts/cliargs.sh")
-                .execute();
+        var os = System.getProperty("os.name");
+        if (os != null && os.toLowerCase().contains("linux")) {
+            new ExecOperation()
+                    .fromProject(this)
+                    .command("scripts/cliargs.sh")
+                    .execute();
+        }
         super.test();
     }
 }
diff --git a/src/main/java/rife/bld/extension/TestNgOperation.java b/src/main/java/rife/bld/extension/TestNgOperation.java
index 7eef93e..298857f 100644
--- a/src/main/java/rife/bld/extension/TestNgOperation.java
+++ b/src/main/java/rife/bld/extension/TestNgOperation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023-2024 the original author or authors.
+ * Copyright 2023-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -75,6 +75,19 @@ public class TestNgOperation extends TestOperation
         return this;
     }
 
+    private String buildClassPath(String... path) {
+        var classpath = new StringBuilder();
+        for (var p : path) {
+            if (!p.isBlank()) {
+                if (!classpath.isEmpty()) {
+                    classpath.append(File.pathSeparator);
+                }
+                classpath.append(p);
+            }
+        }
+        return classpath.toString();
+    }
+
     /**
      * This sets the default maximum number of threads to use for data providers when running tests in parallel.
      * It will only take effect if the parallel mode has been selected (for example,with the
@@ -118,6 +131,30 @@ public class TestNgOperation extends TestOperation
         return this;
     }
 
+    /**
+     * The directory where the reports will be generated
+     *
+     * 

Default is {@code build/test-output})

+ * + * @param directoryPath the directory path + * @return this operation instance + */ + public TestNgOperation directory(File directoryPath) { + return directory(directoryPath.getAbsolutePath()); + } + + /** + * The directory where the reports will be generated + * + *

Default is {@code build/test-output})

+ * + * @param directoryPath the directory path + * @return this operation instance + */ + public TestNgOperation directory(Path directoryPath) { + return directory(directoryPath.toFile()); + } + /** * The list of groups you want to be excluded from this run. * @@ -126,8 +163,7 @@ public class TestNgOperation extends TestOperation * @see #excludeGroups(Collection) #excludeGroups(Collection) */ public TestNgOperation excludeGroups(String... group) { - options_.put("-excludegroups", String.join(",", Arrays.stream(group).filter(this::isNotBlank).toList())); - return this; + return excludeGroups(List.of(group)); } /** @@ -179,11 +215,13 @@ public class TestNgOperation extends TestOperation args.add("-cp"); if (testClasspath_.isEmpty()) { - args.add(String.format("%s:%s:%s:%s", new File(project_.libTestDirectory(), "*"), - new File(project_.libCompileDirectory(), "*"), project_.buildMainDirectory(), - project_.buildTestDirectory())); + args.add(buildClassPath(joinClasspathJar(project_.testClasspathJars()), + joinClasspathJar(project_.compileClasspathJars()), + joinClasspathJar(project_.providedClasspathJars()), + project_.buildMainDirectory().getAbsolutePath(), + project_.buildTestDirectory().getAbsolutePath())); } else { - args.add(String.join(":", testClasspath_)); + args.add(String.join(File.pathSeparator, testClasspath_)); } args.add("org.testng.TestNG"); @@ -201,7 +239,7 @@ public class TestNgOperation extends TestOperation } catch (IOException ioe) { if (LOGGER.isLoggable(Level.SEVERE) && !silent()) { LOGGER.severe("An IO error occurred while accessing the default testng.xml file: " - + ioe.getMessage()); + + ioe.getMessage()); } throw new RuntimeException(ioe); } @@ -285,8 +323,7 @@ public class TestNgOperation extends TestOperation * @see #groups(Collection) #groups(Collection) */ public TestNgOperation groups(String... group) { - options_.put("-groups", String.join(",", Arrays.stream(group).filter(this::isNotBlank).toList())); - return this; + return groups(List.of(group)); } /** @@ -350,6 +387,14 @@ public class TestNgOperation extends TestOperation return this; } + private String joinClasspathJar(List jars) { + if (!jars.isEmpty()) { + return String.join(File.pathSeparator, jars.stream().map(File::getAbsolutePath).toList()); + } else { + return ""; + } + } + /** * The list of {@code .class} files or list of class names implementing {@code ITestListener} or * {@code ISuiteListener} @@ -359,8 +404,7 @@ public class TestNgOperation extends TestOperation * @see #listener(Collection) #listener(Collection) */ public TestNgOperation listener(String... listener) { - options_.put("-listener", String.join(",", Arrays.stream(listener).filter(this::isNotBlank).toList())); - return this; + return listener(List.of(listener)); } /** @@ -423,9 +467,7 @@ public class TestNgOperation extends TestOperation * @see #methodSelectors(Collection) #methodSelectors(Collection) */ public TestNgOperation methodSelectors(String... selector) { - options_.put("-methodselectors", - String.join(",", Arrays.stream(selector).filter(this::isNotBlank).toList())); - return this; + return methodSelectors(List.of(selector)); } /** @@ -452,8 +494,7 @@ public class TestNgOperation extends TestOperation * @see #methods(Collection) #methods(Collection) */ public TestNgOperation methods(String... method) { - methods_.addAll(List.of(method)); - return this; + return methods(List.of(method)); } /** @@ -493,31 +534,24 @@ public class TestNgOperation extends TestOperation } /** - * Fully qualified class name that implements {@code org.testng.ITestObjectFactory} which can be used to create + * The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}. + *

+ * A fully qualified class name that implements {@code org.testng.ITestObjectFactory} which can be used to create * test class and listener instances. * - * @param objectFactory the object factory - * @return this operation instance - */ - public TestNgOperation objectFactory(String objectFactory) { - options_.put("-objectfactory", objectFactory); - return this; - } - - /** - * The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}. - * - * @param factory one or more factories + * @param factory one or more factory * @return this operation instance * @see #objectFactory(Collection) #objectFactory(Collection) */ public TestNgOperation objectFactory(String... factory) { - options_.put("-objectfactory", String.join(",", Arrays.stream(factory).filter(this::isNotBlank).toList())); - return this; + return objectFactory(List.of(factory)); } /** * The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}. + *

+ * A fully qualified class name that implements {@code org.testng.ITestObjectFactory} which can be used to create + * test class and listener instances. * * @param factory the list of factories * @return this operation instance @@ -546,9 +580,7 @@ public class TestNgOperation extends TestOperation * @see #overrideIncludedMethods(Collection) #overrideIncludedMethods(Collection) */ public TestNgOperation overrideIncludedMethods(String... method) { - options_.put("-overrideincludedmethods", - String.join(",", Arrays.stream(method).filter(this::isNotBlank).toList())); - return this; + return overrideIncludedMethods(List.of(method)); } /** @@ -576,8 +608,7 @@ public class TestNgOperation extends TestOperation * @see #packages(Collection) #packages(Collection) */ public TestNgOperation packages(String... name) { - packages_.addAll(Arrays.stream(name).filter(this::isNotBlank).toList()); - return this; + return packages(List.of(name)); } /** @@ -678,10 +709,49 @@ public class TestNgOperation extends TestOperation * * @param directory one or more directories * @return this operation instance - * @see #sourceDir(String...) #sourceDir(String...) + * @see #sourceDir(Collection) */ public TestNgOperation sourceDir(String... directory) { - options_.put("-sourcedir", String.join(";", Arrays.stream(directory).filter(this::isNotBlank).toList())); + return sourceDir(List.of(directory)); + } + + /** + * 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"}). + * + * @param directory one or more directories + * @return this operation instance + * @see #sourceDirFiles(Collection) + */ + public TestNgOperation sourceDir(File... directory) { + return sourceDirFiles(List.of(directory)); + } + + /** + * 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"}). + * + * @param directory one or more directories + * @return this operation instance + * @see #sourceDirPaths(Collection) + */ + public TestNgOperation sourceDir(Path... directory) { + return sourceDirPaths(List.of(directory)); + } + + /** + * 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"}). + * + * @param directory the list of directories + * @return this operation instance + * @see #sourceDir(String...) + */ + public TestNgOperation sourceDir(Collection directory) { + options_.put("-sourcedir", String.join(";", directory.stream().filter(this::isNotBlank).toList())); return this; } @@ -692,11 +762,23 @@ public class TestNgOperation extends TestOperation * * @param directory the list of directories * @return this operation instance - * @see #sourceDir(String...) #sourceDir(String...) + * @see #sourceDir(File...) */ - public TestNgOperation sourceDir(Collection directory) { - options_.put("-sourcedir", String.join(";", directory.stream().filter(this::isNotBlank).toList())); - return this; + public TestNgOperation sourceDirFiles(Collection directory) { + return sourceDir(directory.stream().map(File::getAbsolutePath).toList()); + } + + /** + * 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"}). + * + * @param directory the list of directories + * @return this operation instance + * @see #sourceDir(Path...) + */ + public TestNgOperation sourceDirPaths(Collection directory) { + return sourceDirFiles(directory.stream().map(Path::toFile).toList()); } /** @@ -708,9 +790,7 @@ public class TestNgOperation extends TestOperation * @see #spiListenersToSkip(Collection) #spiListenersToSkip(Collection) */ public TestNgOperation spiListenersToSkip(String... listenerToSkip) { - options_.put("-spilistenerstoskip", - String.join(",", Arrays.stream(listenerToSkip).filter(this::isNotBlank).toList())); - return this; + return spiListenersToSkip(List.of(listenerToSkip)); } /** @@ -765,8 +845,7 @@ public class TestNgOperation extends TestOperation * @see #suites(Collection) #suites(Collection) */ public TestNgOperation suites(String... suite) { - suites_.addAll(Arrays.stream(suite).filter(this::isNotBlank).toList()); - return this; + return suites(List.of(suite)); } /** @@ -813,8 +892,7 @@ public class TestNgOperation extends TestOperation * @see #testClass(Collection) #testClass(Collection) */ public TestNgOperation testClass(String... aClass) { - options_.put("-testclass", String.join(",", Arrays.stream(aClass).filter(this::isNotBlank).toList())); - return this; + return testClass(List.of(aClass)); } /** @@ -839,8 +917,7 @@ public class TestNgOperation extends TestOperation * @see #testClasspath(String...) #testClasspath(String...) */ public TestNgOperation testClasspath(String... entry) { - testClasspath_.addAll(Arrays.stream(entry).filter(this::isNotBlank).toList()); - return this; + return testClasspath(List.of(entry)); } /** @@ -901,9 +978,7 @@ public class TestNgOperation extends TestOperation * @see #testNames(Collection) #testNames(Collection) */ public TestNgOperation testNames(String... name) { - options_.put("-testnames", - Arrays.stream(name).filter(this::isNotBlank).map(s -> '"' + s + '"').collect(Collectors.joining(","))); - return this; + return testNames(List.of(name)); } /** @@ -1004,10 +1079,10 @@ public class TestNgOperation extends TestOperation var temp = tempFile(); try (var bufWriter = Files.newBufferedWriter(Paths.get(temp.getPath()))) { bufWriter.write("" + - "" + - "" + - "" + - ""); + "" + + "" + + "" + + ""); for (var p : packages_) { bufWriter.write(String.format("", p)); } @@ -1031,6 +1106,30 @@ public class TestNgOperation extends TestOperation return this; } + /** + * This attribute should contain the path to a valid XML file inside the test jar + * (e.g. {@code "resources/testng.xml"}). The default is {@code testng.xml}, which means a file called + * {@code testng.xml} at the root of the jar file. This option will be ignored unless a test jar is specified. + * + * @param path the path + * @return this operation instance + */ + public TestNgOperation xmlPathInJar(File path) { + return xmlPathInJar(path.getAbsolutePath()); + } + + /** + * This attribute should contain the path to a valid XML file inside the test jar + * (e.g. {@code "resources/testng.xml"}). The default is {@code testng.xml}, which means a file called + * {@code testng.xml} at the root of the jar file. This option will be ignored unless a test jar is specified. + * + * @param path the path + * @return this operation instance + */ + public TestNgOperation xmlPathInJar(Path path) { + return xmlPathInJar(path.toFile()); + } + /** * Parallel Mechanisms */ diff --git a/src/test/java/rife/bld/extension/TestNgExample.java b/src/test/java/rife/bld/extension/TestNgExample.java index c2dc3e0..faa223a 100644 --- a/src/test/java/rife/bld/extension/TestNgExample.java +++ b/src/test/java/rife/bld/extension/TestNgExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,8 +22,9 @@ package rife.bld.extension; * @author Erik C. Thauvin * @since 1.0 */ -@SuppressWarnings("PMD.TestClassWithoutTestCases") +@SuppressWarnings({"PMD.TestClassWithoutTestCases", "unused"}) class TestNgExample { + @SuppressWarnings("SameReturnValue") public String getMessage() { return "Hello World!"; } diff --git a/src/test/java/rife/bld/extension/TestNgExampleTest.java b/src/test/java/rife/bld/extension/TestNgExampleTest.java index a2c35b9..6d3c9b0 100644 --- a/src/test/java/rife/bld/extension/TestNgExampleTest.java +++ b/src/test/java/rife/bld/extension/TestNgExampleTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import org.testng.annotations.Test; * @author Erik C. Thauvin * @since 1.0 */ +@SuppressWarnings("unused") class TestNgExampleTest { private final TestNgExample example = new TestNgExample(); diff --git a/src/test/java/rife/bld/extension/TestNgOperationTest.java b/src/test/java/rife/bld/extension/TestNgOperationTest.java index 83b1f80..d4f3193 100644 --- a/src/test/java/rife/bld/extension/TestNgOperationTest.java +++ b/src/test/java/rife/bld/extension/TestNgOperationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,10 @@ package rife.bld.extension; +import org.assertj.core.api.AutoCloseableSoftAssertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; import rife.bld.Project; import rife.bld.blueprints.BaseProjectBlueprint; import rife.bld.operations.exceptions.ExitStatusException; @@ -50,13 +53,14 @@ class TestNgOperationTest { } @Test + @EnabledOnOs(OS.LINUX) void testCheckAllParameters() throws IOException { var args = Files.readAllLines(Paths.get("src", "test", "resources", "testng-args.txt")); assertThat(args).isNotEmpty(); var params = new TestNgOperation() - .fromProject(new BaseProjectBlueprint(new File("examples"), "com.example", "Examples")) + .fromProject(new BaseProjectBlueprint(new File("examples"), "com.example", "examples", "Examples")) .alwaysRunListeners(true) .dataProviderThreadCount(1) .dependencyInjectorFactory("injectorfactory") @@ -97,15 +101,17 @@ class TestNgOperationTest { .xmlPathInJar("jarPath") .executeConstructProcessCommandList(); - for (var p : args) { - var found = false; - for (var a : params) { - if (a.startsWith(p)) { - found = true; - break; + try (var softly = new AutoCloseableSoftAssertions()) { + for (var p : args) { + var found = false; + for (var a : params) { + if (a.startsWith(p)) { + found = true; + break; + } } + softly.assertThat(found).as(p + " not found.").isTrue(); } - assertThat(found).as(p + " not found.").isTrue(); } } @@ -140,8 +146,16 @@ class TestNgOperationTest { @Test void testDirectory() { + var foo = new File("FOO"); + var op = new TestNgOperation().directory(FOO); - assertThat(op.options().get("-d")).isEqualTo(FOO); + assertThat(op.options().get("-d")).as("as string").isEqualTo(FOO); + + op = new TestNgOperation().directory(foo); + assertThat(op.options().get("-d")).as("as file").isEqualTo(foo.getAbsolutePath()); + + op = new TestNgOperation().directory(foo.toPath()); + assertThat(op.options().get("-d")).as("as path").isEqualTo(foo.getAbsolutePath()); } @Test @@ -401,11 +415,28 @@ class TestNgOperationTest { @Test void testSourceDir() { + var foo = new File(FOO); + var bar = new File(BAR); + + var foobar = String.format("%s;%s", 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")).as("String...").isEqualTo(foobar); op = new TestNgOperation().sourceDir(List.of(FOO, BAR)); - assertThat(op.options().get("-sourcedir")).as("as list").isEqualTo(String.format("%s;%s", FOO, BAR)); + assertThat(op.options().get("-sourcedir")).as("List(String...)").isEqualTo(foobar); + + foobar = String.format("%s;%s", foo.getAbsolutePath(), bar.getAbsolutePath()); + op = new TestNgOperation().sourceDir(foo, bar); + assertThat(op.options().get("-sourcedir")).as("File...").isEqualTo(foobar); + + op = new TestNgOperation().sourceDirFiles(List.of(foo, bar)); + assertThat(op.options().get("-sourcedir")).as("List(String...)").isEqualTo(foobar); + + op = new TestNgOperation().sourceDir(foo.toPath(), bar.toPath()); + assertThat(op.options().get("-sourcedir")).as("Path...").isEqualTo(foobar); + + op = new TestNgOperation().sourceDirPaths(List.of(foo.toPath(), bar.toPath())); + assertThat(op.options().get("-sourcedir")).as("List(Path...)").isEqualTo(foobar); } @Test @@ -479,7 +510,14 @@ class TestNgOperationTest { @Test void testXmlPathInJar() { + var foo = new File(FOO); var op = new TestNgOperation().xmlPathInJar(FOO); - assertThat(op.options().get("-xmlpathinjar")).isEqualTo(FOO); + assertThat(op.options().get("-xmlpathinjar")).as("as string").isEqualTo(FOO); + + op = new TestNgOperation().xmlPathInJar(foo); + assertThat(op.options().get("-xmlpathinjar")).as("as file").isEqualTo(foo.getAbsolutePath()); + + op = new TestNgOperation().xmlPathInJar(foo.toPath()); + assertThat(op.options().get("-xmlpathinjar")).as("as path").isEqualTo(foo.getAbsolutePath()); } }