+
+ init {
+ args.addAll(
+ "--update",
+ // Use a constant time to make the JAR reproducible.
+ "--date=$CONSTANT_TIME_FOR_ZIP_ENTRIES",
+ )
+ }
+
+ override fun execute(t: Task) {
+ operations.exec {
+ executable = javaLauncher.get()
+ .metadata.installationPath.file("bin/jar").asFile.absolutePath
+ args = this@UpdateJarAction.args.get()
+ }
+ }
+}
diff --git a/gradle/plugins/settings.gradle.kts b/gradle/plugins/settings.gradle.kts
index 0b948c46d94f..728290a2cad6 100644
--- a/gradle/plugins/settings.gradle.kts
+++ b/gradle/plugins/settings.gradle.kts
@@ -1,9 +1,3 @@
-val expectedJavaVersion = JavaVersion.VERSION_17
-val actualJavaVersion = JavaVersion.current()
-require(actualJavaVersion == expectedJavaVersion) {
- "The JUnit 5 build must be executed with Java ${expectedJavaVersion.majorVersion}. Currently executing with Java ${actualJavaVersion.majorVersion}."
-}
-
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
@@ -14,7 +8,10 @@ dependencyResolutionManagement {
rootProject.name = "plugins"
+includeBuild("../base")
+
include("build-parameters")
include("common")
+include("code-generator")
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
diff --git a/gradle/scripts/checkBuildReproducibility.sh b/gradle/scripts/checkBuildReproducibility.sh
index b07275624da1..c434fc778a44 100755
--- a/gradle/scripts/checkBuildReproducibility.sh
+++ b/gradle/scripts/checkBuildReproducibility.sh
@@ -7,13 +7,19 @@ export SOURCE_DATE_EPOCH=$(date +%s)
function calculate_checksums() {
OUTPUT=$1
- ./gradlew --no-build-cache clean assemble --parallel -Porg.gradle.java.installations.auto-download=false -Dscan.tag.Reproducibility
+ ./gradlew \
+ --configuration-cache \
+ --no-build-cache \
+ -Porg.gradle.java.installations.auto-download=false \
+ -Dscan.tag.Reproducibility \
+ clean \
+ assemble
find . -name '*.jar' \
| grep '/build/libs/' \
| grep --invert-match 'javadoc' \
| sort \
- | xargs sha256sum > ${OUTPUT}
+ | xargs sha256sum > "${OUTPUT}"
}
diff --git a/gradle/scripts/publishDocumentationSnapshotOnlyIfNecessary.sh b/gradle/scripts/publishDocumentationSnapshotOnlyIfNecessary.sh
deleted file mode 100755
index ecd0482a2368..000000000000
--- a/gradle/scripts/publishDocumentationSnapshotOnlyIfNecessary.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env bash
-
-readonly checksum_directory='documentation/build/checksum'
-readonly current="${checksum_directory}/current-checksum.txt"
-readonly published="${checksum_directory}/published-checksum.txt"
-readonly github_pages_url='https://raw.githubusercontent.com/junit-team/junit5/gh-pages/docs/snapshot/published-checksum.txt'
-
-#
-# always generate current sums
-#
-echo "Generating checksum file ${current}..."
-mkdir --parents "${checksum_directory}"
-md5sum documentation/documentation.gradle.kts > "${current}"
-md5sum $(find documentation/src -type f) >> "${current}"
-# skip module junit-bom because it doesn't contain relevant documentation
-md5sum $(find junit-jupiter -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-jupiter-api -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-jupiter-engine -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-jupiter-migrationsupport -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-jupiter-params -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-commons -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-console -wholename '**/src/main/*.java') >> "${current}"
-# skip module junit-platform-console-standalone because it doesn't contain relevant documentation
-md5sum $(find junit-platform-engine -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-jfr -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-launcher -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-reporting -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-runner -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-suite -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-suite-api -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-suite-commons -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-suite-engine -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-platform-testkit -wholename '**/src/main/*.java') >> "${current}"
-md5sum $(find junit-vintage-engine -wholename '**/src/main/*.java') >> "${current}"
-# skip module platform-tests because it doesn't contain relevant documentation
-# skip module platform-tooling-support-tests because it doesn't contain relevant documentation
-sort --output "${current}" "${current}"
-echo
-md5sum "${current}"
-
-#
-# compare current with published sums
-#
-curl --silent --output "${published}" "${github_pages_url}"
-md5sum "${published}"
-if cmp --silent "${current}" "${published}" ; then
- #
- # no changes detected: we're done
- #
- echo
- echo "Already published documentation with same source checksum."
- echo
-else
- #
- # update checksum file and trigger new documentation build and upload
- #
- echo
- echo "Creating and publishing documentation..."
- echo
- cp --force "${current}" "${published}"
- ./gradlew gitPublishPush -Porg.gradle.java.installations.auto-download=false -Dscan.tag.Documentation
-fi
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 033e24c4cdf4..2c3521197d7c 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c2447881d454..68e8816d71c9 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionSha256Sum=03ec176d388f2aa99defcadc3ac6adf8dd2bce5145a129659537c0874dea5ad1
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
+distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index fcb6fca147c0..f5feea6d6b11 100755
--- a/gradlew
+++ b/gradlew
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# SPDX-License-Identifier: Apache-2.0
+#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -83,7 +85,9 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -144,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC3045
+ # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -152,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC3045
+ # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -201,11 +205,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-# Collect all arguments for the java command;
-# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-# shell script including quotes and variable substitutions, so put them in
-# double quotes to make sure that they get re-expanded; and
-# * put everything else in single quotes, so that it's not re-expanded.
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
diff --git a/gradlew.bat b/gradlew.bat
index 93e3f59f135d..9d21a21834d5 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
diff --git a/junit-bom/README.md b/junit-bom/README.md
index 907a361c665a..e3c52f7f76d1 100644
--- a/junit-bom/README.md
+++ b/junit-bom/README.md
@@ -4,5 +4,5 @@ This module provides a Bill of Materials POM to ease dependency management using
or [Gradle]. Please refer to the [User Guide] for details.
[Maven]: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies
-[Gradle]: https://docs.gradle.org/current/userguide/managing_transitive_dependencies.html#sec:bom_import
+[Gradle]: https://docs.gradle.org/current/userguide/platforms.html#sub:bom_import
[User Guide]: https://junit.org/junit5/docs/current/user-guide/#dependency-metadata-junit-bom
diff --git a/junit-jupiter-api/junit-jupiter-api.gradle.kts b/junit-jupiter-api/junit-jupiter-api.gradle.kts
index 7dd03a78f4e9..bdf4c359550f 100644
--- a/junit-jupiter-api/junit-jupiter-api.gradle.kts
+++ b/junit-jupiter-api/junit-jupiter-api.gradle.kts
@@ -1,5 +1,6 @@
plugins {
id("junitbuild.kotlin-library-conventions")
+ id("junitbuild.code-generator")
`java-test-fixtures`
}
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AfterAll.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AfterAll.java
index 52743ebef416..7cbbfd7b0f15 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AfterAll.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AfterAll.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -29,33 +29,31 @@
*
* Method Signatures
*
- * {@code @AfterAll} methods must have a {@code void} return type and must be
- * {@code static} by default. Consequently, {@code @AfterAll} methods are not
- * supported in {@link Nested @Nested} test classes or as interface default
- * methods unless the test class is annotated with
- * {@link TestInstance @TestInstance(Lifecycle.PER_CLASS)}.
- * However, beginning with Java 16 {@code @AfterAll} methods may be declared as
- * {@code static} in {@link Nested @Nested} test classes, and the
- * {@code Lifecycle.PER_CLASS} restriction no longer applies. {@code @AfterAll}
- * methods may optionally declare parameters to be resolved by
+ *
{@code @AfterAll} methods must have a {@code void} return type and must
+ * be {@code static} by default. Consequently, {@code @AfterAll} methods are
+ * not supported in {@link Nested @Nested} test classes or as interface
+ * default methods unless the test class is annotated with
+ * {@link TestInstance @TestInstance(Lifecycle.PER_CLASS)}. However, beginning
+ * with Java 16 {@code @AfterAll} methods may be declared as {@code static} in
+ * {@link Nested @Nested} test classes, in which case the {@code Lifecycle.PER_CLASS}
+ * restriction no longer applies. In addition, {@code @AfterAll} methods may
+ * optionally declare parameters to be resolved by
* {@link org.junit.jupiter.api.extension.ParameterResolver ParameterResolvers}.
*
- *
Using {@code private} visibility for {@code @BeforeAll} methods is
- * strongly discouraged and will be disallowed in a future release.
+ *
Using {@code private} visibility for {@code @AfterAll} methods is strongly
+ * discouraged and will be disallowed in a future release.
*
*
Inheritance and Execution Order
*
- * {@code @AfterAll} methods are inherited from superclasses as long as
- * they are not hidden (default mode with {@code static} modifier),
- * overridden, or superseded (i.e., replaced based on
- * signature only, irrespective of Java's visibility rules). Furthermore,
- * {@code @AfterAll} methods from superclasses will be executed before
- * {@code @AfterAll} methods in subclasses.
+ *
{@code @AfterAll} methods are inherited from superclasses as long as they
+ * are not overridden according to the visibility rules of the Java
+ * language. Furthermore, {@code @AfterAll} methods from superclasses will be
+ * executed after {@code @AfterAll} methods in subclasses.
*
- *
Similarly, {@code @AfterAll} methods declared in an interface are
- * inherited as long as they are not hidden or overridden,
- * and {@code @AfterAll} methods from an interface will be executed after
- * {@code @AfterAll} methods in the class that implements the interface.
+ *
Similarly, {@code @AfterAll} methods declared in an interface are inherited
+ * as long as they are not overridden, and {@code @AfterAll} methods from an
+ * interface will be executed after {@code @AfterAll} methods in the class that
+ * implements the interface.
*
*
JUnit Jupiter does not guarantee the execution order of multiple
* {@code @AfterAll} methods that are declared within a single test class or
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AfterEach.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AfterEach.java
index 8dfd018fa4f9..bf1d90853f33 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AfterEach.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AfterEach.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -29,18 +29,19 @@
*
Method Signatures
*
* {@code @AfterEach} methods must have a {@code void} return type and must
- * not be {@code static}. Using {@code private} visibility is strongly
- * discouraged and will be disallowed in a future release.
- * They may optionally declare parameters to be resolved by
+ * not be {@code static}. In addition, {@code @AfterEach} methods may optionally
+ * declare parameters to be resolved by
* {@link org.junit.jupiter.api.extension.ParameterResolver ParameterResolvers}.
*
+ *
Using {@code private} visibility for {@code @AfterEach} methods is strongly
+ * discouraged and will be disallowed in a future release.
+ *
*
Inheritance and Execution Order
*
* {@code @AfterEach} methods are inherited from superclasses as long as they
- * are not overridden or superseded (i.e., replaced based on
- * signature only, irrespective of Java's visibility rules). Furthermore,
- * {@code @AfterEach} methods from superclasses will be executed after
- * {@code @AfterEach} methods in subclasses.
+ * are not overridden according to the visibility rules of the Java
+ * language. Furthermore, {@code @AfterEach} methods from superclasses will be
+ * executed after {@code @AfterEach} methods in subclasses.
*
*
Similarly, {@code @AfterEach} methods declared as interface default
* methods are inherited as long as they are not overridden, and
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertAll.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertAll.java
index 601e9ecf8d9c..29b1218ff060 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertAll.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertAll.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertArrayEquals.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertArrayEquals.java
index 45d37399c0e1..7da0accd15b4 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertArrayEquals.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertArrayEquals.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertDoesNotThrow.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertDoesNotThrow.java
index 2d424aa7ed39..e83f4508daaf 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertDoesNotThrow.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertDoesNotThrow.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertEquals.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertEquals.java
index 2a46cea309f3..558d9afc8147 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertEquals.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertEquals.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertFalse.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertFalse.java
index 5291a6ac6ead..83dad97da5ce 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertFalse.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertFalse.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertInstanceOf.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertInstanceOf.java
index 2f265f3fc237..60d9b278e5ee 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertInstanceOf.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertInstanceOf.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertIterableEquals.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertIterableEquals.java
index b837c449bca2..820b5365e2b3 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertIterableEquals.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertIterableEquals.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java
index 03e79081bd9e..ef25f47e1dd3 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotEquals.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotEquals.java
index 5a37b059a0fc..4bdd3376248c 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotEquals.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotEquals.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotNull.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotNull.java
index 43787ab8c27b..8d63cd76bdd6 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotNull.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotNull.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotSame.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotSame.java
index 66f795c7a75a..606934f317ca 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotSame.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNotSame.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNull.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNull.java
index 53ceb4ce099a..9d674d8c59c0 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNull.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertNull.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertSame.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertSame.java
index feafa36231c9..8e9278d19c84 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertSame.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertSame.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertThrows.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertThrows.java
index b61570647cb5..02947d1637af 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertThrows.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertThrows.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertThrowsExactly.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertThrowsExactly.java
index 8a669388b709..830dca520260 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertThrowsExactly.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertThrowsExactly.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeout.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeout.java
index bfd1f66806ba..64b625b6c7fa 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeout.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeout.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -69,7 +69,7 @@ private static T assertTimeout(Duration timeout, ThrowingSupplier supplie
result = supplier.get();
}
catch (Throwable ex) {
- throwAsUncheckedException(ex);
+ throw throwAsUncheckedException(ex);
}
long timeElapsed = System.currentTimeMillis() - start;
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeoutPreemptively.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeoutPreemptively.java
index 4ff96b71556d..4585bb0e8927 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeoutPreemptively.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeoutPreemptively.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTrue.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTrue.java
index cf4f94277a93..0cb0bbc245bd 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTrue.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTrue.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertionFailureBuilder.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertionFailureBuilder.java
index 8d0341d3cb46..5f826a88cb8d 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertionFailureBuilder.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertionFailureBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertionUtils.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertionUtils.java
index 48a74da2ce96..3ac27f22b1dd 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertionUtils.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertionUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java
index 4be1561689dc..3f5df08971a0 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -59,22 +59,26 @@
* Preemptive Timeouts
*
* The various {@code assertTimeoutPreemptively()} methods in this class
- * execute the provided {@code executable} or {@code supplier} in a different
- * thread than that of the calling code. This behavior can lead to undesirable
- * side effects if the code that is executed within the {@code executable} or
- * {@code supplier} relies on {@link ThreadLocal} storage.
+ * execute the provided callback ({@code executable} or {@code supplier}) in a
+ * different thread than that of the calling code. If the timeout is exceeded,
+ * an attempt will be made to preemptively abort execution of the callback by
+ * {@linkplain Thread#interrupt() interrupting} the callback's thread. If the
+ * callback's thread does not return when interrupted, the thread will continue
+ * to run in the background after the {@code assertTimeoutPreemptively()} method
+ * has returned.
*
- *
One common example of this is the transactional testing support in the Spring
- * Framework. Specifically, Spring's testing support binds transaction state to
- * the current thread (via a {@code ThreadLocal}) before a test method is invoked.
- * Consequently, if an {@code executable} or {@code supplier} provided to
- * {@code assertTimeoutPreemptively()} invokes Spring-managed components that
- * participate in transactions, any actions taken by those components will not be
- * rolled back with the test-managed transaction. On the contrary, such actions
- * will be committed to the persistent store (e.g., relational database) even
- * though the test-managed transaction is rolled back.
- *
- *
Similar side effects may be encountered with other frameworks that rely on
+ *
Furthermore, the behavior of {@code assertTimeoutPreemptively()} methods
+ * can lead to undesirable side effects if the code that is executed within the
+ * callback relies on {@link ThreadLocal} storage. One common example of this is
+ * the transactional testing support in the Spring Framework. Specifically, Spring's
+ * testing support binds transaction state to the current thread (via a
+ * {@code ThreadLocal}) before a test method is invoked. Consequently, if a
+ * callback provided to {@code assertTimeoutPreemptively()} invokes Spring-managed
+ * components that participate in transactions, any actions taken by those
+ * components will not be rolled back with the test-managed transaction. On the
+ * contrary, such actions will be committed to the persistent store (e.g.,
+ * relational database) even though the test-managed transaction is rolled back.
+ * Similar side effects may be encountered with other frameworks that rely on
* {@code ThreadLocal} storage.
*
*
Extensibility
@@ -3066,7 +3070,11 @@ public static T assertThrowsExactly(Class expectedType,
* If you do not want to perform additional checks on the exception instance,
* ignore the return value.
*
- *
Fails with the supplied failure {@code message}.
+ *
Fails with the supplied failure {@code message}. Note that the supplied
+ * {@code message} is not the expected message of the thrown
+ * exception. To assert the expected message of the thrown exception, you must
+ * use a separate, subsequent assertion against the exception returned from
+ * this method.
*
* @since 5.8
*/
@@ -3084,7 +3092,11 @@ public static T assertThrowsExactly(Class expectedType,
* thrown, this method will fail.
*
* If necessary, the failure message will be retrieved lazily from the
- * supplied {@code messageSupplier}.
+ * supplied {@code messageSupplier}. Note that the failure message is
+ * not the expected message of the thrown exception. To
+ * assert the expected message of the thrown exception, you must use a
+ * separate, subsequent assertion against the exception returned from this
+ * method.
*
*
If you do not want to perform additional checks on the exception instance,
* ignore the return value.
@@ -3101,11 +3113,16 @@ public static T assertThrowsExactly(Class expectedType,
* Assert that execution of the supplied {@code executable} throws
* an exception of the {@code expectedType} and return the exception.
*
- * If no exception is thrown, or if an exception of a different type is
- * thrown, this method will fail.
+ *
The assertion passes if the thrown exception type is the same as
+ * {@code expectedType} or a subtype thereof. To check for the exact thrown
+ * type use {@link #assertThrowsExactly(Class, Executable) assertThrowsExactly}.
+ * If no exception is thrown, or if an exception of a different type is thrown,
+ * this method will fail.
*
*
If you do not want to perform additional checks on the exception instance,
* ignore the return value.
+ *
+ * @see #assertThrowsExactly(Class, Executable)
*/
public static T assertThrows(Class expectedType, Executable executable) {
return AssertThrows.assertThrows(expectedType, executable);
@@ -3115,13 +3132,22 @@ public static T assertThrows(Class expectedType, Execut
* Assert that execution of the supplied {@code executable} throws
* an exception of the {@code expectedType} and return the exception.
*
- * If no exception is thrown, or if an exception of a different type is
- * thrown, this method will fail.
+ *
The assertion passes if the thrown exception type is the same as
+ * {@code expectedType} or a subtype thereof. To check for the exact thrown
+ * type use {@link #assertThrowsExactly(Class, Executable, String) assertThrowsExactly}.
+ * If no exception is thrown, or if an exception of a different type is thrown,
+ * this method will fail.
*
*
If you do not want to perform additional checks on the exception instance,
* ignore the return value.
*
- *
Fails with the supplied failure {@code message}.
+ *
Fails with the supplied failure {@code message}. Note that the supplied
+ * {@code message} is not the expected message of the thrown
+ * exception. To assert the expected message of the thrown exception, you must
+ * use a separate, subsequent assertion against the exception returned from
+ * this method.
+ *
+ * @see #assertThrowsExactly(Class, Executable, String)
*/
public static T assertThrows(Class expectedType, Executable executable, String message) {
return AssertThrows.assertThrows(expectedType, executable, message);
@@ -3131,14 +3157,23 @@ public static T assertThrows(Class expectedType, Execut
* Assert that execution of the supplied {@code executable} throws
* an exception of the {@code expectedType} and return the exception.
*
- * If no exception is thrown, or if an exception of a different type is
- * thrown, this method will fail.
+ *
The assertion passes if the thrown exception type is the same as
+ * {@code expectedType} or a subtype thereof. To check for the exact thrown
+ * type use {@link #assertThrowsExactly(Class, Executable, Supplier) assertThrowsExactly}.
+ * If no exception is thrown, or if an exception of a different type is thrown,
+ * this method will fail.
*
*
If necessary, the failure message will be retrieved lazily from the
- * supplied {@code messageSupplier}.
+ * supplied {@code messageSupplier}. Note that the failure message is
+ * not the expected message of the thrown exception. To
+ * assert the expected message of the thrown exception, you must use a
+ * separate, subsequent assertion against the exception returned from this
+ * method.
*
*
If you do not want to perform additional checks on the exception instance,
* ignore the return value.
+ *
+ * @see #assertThrowsExactly(Class, Executable, Supplier)
*/
public static T assertThrows(Class expectedType, Executable executable,
Supplier messageSupplier) {
@@ -3410,11 +3445,8 @@ public static T assertTimeout(Duration timeout, ThrowingSupplier supplier
* Assert that execution of the supplied {@code executable}
* completes before the given {@code timeout} is exceeded.
*
- * Note: the {@code executable} will be executed in a different thread than
- * that of the calling code. Furthermore, execution of the {@code executable} will
- * be preemptively aborted if the timeout is exceeded. See the
- * {@linkplain Assertions Preemptive Timeouts} section of the class-level
- * Javadoc for a discussion of possible undesirable side effects.
+ *
See the {@linkplain Assertions Preemptive Timeouts} section of the
+ * class-level Javadoc for further details.
*
* @see #assertTimeoutPreemptively(Duration, Executable, String)
* @see #assertTimeoutPreemptively(Duration, Executable, Supplier)
@@ -3431,11 +3463,8 @@ public static void assertTimeoutPreemptively(Duration timeout, Executable execut
* Assert that execution of the supplied {@code executable}
* completes before the given {@code timeout} is exceeded.
*
- *
Note: the {@code executable} will be executed in a different thread than
- * that of the calling code. Furthermore, execution of the {@code executable} will
- * be preemptively aborted if the timeout is exceeded. See the
- * {@linkplain Assertions Preemptive Timeouts} section of the class-level
- * Javadoc for a discussion of possible undesirable side effects.
+ *
See the {@linkplain Assertions Preemptive Timeouts} section of the
+ * class-level Javadoc for further details.
*
*
Fails with the supplied failure {@code message}.
*
@@ -3454,11 +3483,8 @@ public static void assertTimeoutPreemptively(Duration timeout, Executable execut
* Assert that execution of the supplied {@code executable}
* completes before the given {@code timeout} is exceeded.
*
- *
Note: the {@code executable} will be executed in a different thread than
- * that of the calling code. Furthermore, execution of the {@code executable} will
- * be preemptively aborted if the timeout is exceeded. See the
- * {@linkplain Assertions Preemptive Timeouts} section of the class-level
- * Javadoc for a discussion of possible undesirable side effects.
+ *
See the {@linkplain Assertions Preemptive Timeouts} section of the
+ * class-level Javadoc for further details.
*
*
If necessary, the failure message will be retrieved lazily from the
* supplied {@code messageSupplier}.
@@ -3481,13 +3507,10 @@ public static void assertTimeoutPreemptively(Duration timeout, Executable execut
* Assert that execution of the supplied {@code supplier}
* completes before the given {@code timeout} is exceeded.
*
- *
If the assertion passes then the {@code supplier}'s result is returned.
+ *
See the {@linkplain Assertions Preemptive Timeouts} section of the
+ * class-level Javadoc for further details.
*
- *
Note: the {@code supplier} will be executed in a different thread than
- * that of the calling code. Furthermore, execution of the {@code supplier} will
- * be preemptively aborted if the timeout is exceeded. See the
- * {@linkplain Assertions Preemptive Timeouts} section of the class-level
- * Javadoc for a discussion of possible undesirable side effects.
+ *
If the assertion passes then the {@code supplier}'s result is returned.
*
* @see #assertTimeoutPreemptively(Duration, Executable)
* @see #assertTimeoutPreemptively(Duration, Executable, String)
@@ -3504,13 +3527,10 @@ public static T assertTimeoutPreemptively(Duration timeout, ThrowingSupplier
* Assert that execution of the supplied {@code supplier}
* completes before the given {@code timeout} is exceeded.
*
- * If the assertion passes then the {@code supplier}'s result is returned.
+ *
See the {@linkplain Assertions Preemptive Timeouts} section of the
+ * class-level Javadoc for further details.
*
- *
Note: the {@code supplier} will be executed in a different thread than
- * that of the calling code. Furthermore, execution of the {@code supplier} will
- * be preemptively aborted if the timeout is exceeded. See the
- * {@linkplain Assertions Preemptive Timeouts} section of the class-level
- * Javadoc for a discussion of possible undesirable side effects.
+ *
If the assertion passes then the {@code supplier}'s result is returned.
*
*
Fails with the supplied failure {@code message}.
*
@@ -3529,13 +3549,10 @@ public static T assertTimeoutPreemptively(Duration timeout, ThrowingSupplier
* Assert that execution of the supplied {@code supplier}
* completes before the given {@code timeout} is exceeded.
*
- * If the assertion passes then the {@code supplier}'s result is returned.
+ *
See the {@linkplain Assertions Preemptive Timeouts} section of the
+ * class-level Javadoc for further details.
*
- *
Note: the {@code supplier} will be executed in a different thread than
- * that of the calling code. Furthermore, execution of the {@code supplier} will
- * be preemptively aborted if the timeout is exceeded. See the
- * {@linkplain Assertions Preemptive Timeouts} section of the class-level
- * Javadoc for a discussion of possible undesirable side effects.
+ *
If the assertion passes then the {@code supplier}'s result is returned.
*
*
If necessary, the failure message will be retrieved lazily from the
* supplied {@code messageSupplier}.
@@ -3556,18 +3573,15 @@ public static T assertTimeoutPreemptively(Duration timeout, ThrowingSupplier
* Assert that execution of the supplied {@code supplier}
* completes before the given {@code timeout} is exceeded.
*
+ * See the {@linkplain Assertions Preemptive Timeouts} section of the
+ * class-level Javadoc for further details.
+ *
*
If the assertion passes then the {@code supplier}'s result is returned.
*
*
In the case the assertion does not pass, the supplied
* {@link TimeoutFailureFactory} is invoked to create an exception which is
* then thrown.
*
- *
Note: the {@code supplier} will be executed in a different thread than
- * that of the calling code. Furthermore, execution of the {@code supplier} will
- * be preemptively aborted if the timeout is exceeded. See the
- * {@linkplain Assertions Preemptive Timeouts} section of the class-level
- * Javadoc for a discussion of possible undesirable side effects.
- *
*
If necessary, the failure message will be retrieved lazily from the
* supplied {@code messageSupplier}.
*
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assumptions.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assumptions.java
index d0448a89778e..f1ade0746475 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assumptions.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assumptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -248,7 +248,7 @@ public static void assumingThat(boolean assumption, Executable executable) {
executable.execute();
}
catch (Throwable t) {
- ExceptionUtils.throwAsUncheckedException(t);
+ throw ExceptionUtils.throwAsUncheckedException(t);
}
}
}
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AutoClose.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AutoClose.java
new file mode 100644
index 000000000000..0a29faba7a95
--- /dev/null
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AutoClose.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015-2024 the original author or authors.
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v2.0 which
+ * accompanies this distribution and is available at
+ *
+ * https://www.eclipse.org/legal/epl-v20.html
+ */
+
+package org.junit.jupiter.api;
+
+import static org.apiguardian.api.API.Status.EXPERIMENTAL;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apiguardian.api.API;
+
+/**
+ * {@code @AutoClose} is used to indicate that an annotated field will be
+ * automatically closed after test execution.
+ *
+ *
{@code @AutoClose} fields may be either {@code static} or non-static. If
+ * the value of an {@code @AutoClose} field is {@code null} when it is evaluated
+ * the field will be ignored, but a warning message will be logged to inform you.
+ *
+ *
By default, {@code @AutoClose} expects the value of the annotated field to
+ * implement a {@code close()} method that will be invoked to close the resource.
+ * However, developers can customize the name of the {@code close} method via the
+ * {@link #value} attribute. For example, {@code @AutoClose("shutdown")} instructs
+ * JUnit to look for a {@code shutdown()} method to close the resource.
+ *
+ *
{@code @AutoClose} may be used as a meta-annotation in order to create a
+ * custom composed annotation that inherits the semantics of
+ * {@code @AutoClose}.
+ *
+ *
Inheritance
+ *
+ * {@code @AutoClose} fields are inherited from superclasses. Furthermore,
+ * {@code @AutoClose} fields from subclasses will be closed before
+ * {@code @AutoClose} fields in superclasses.
+ *
+ *
Evaluation Order
+ *
+ * When multiple {@code @AutoClose} fields exist within a given test class,
+ * the order in which the resources are closed depends on an algorithm that is
+ * deterministic but intentionally nonobvious. This ensures that subsequent runs
+ * of a test suite close resources in the same order, thereby allowing for
+ * repeatable builds.
+ *
+ *
Scope and Lifecycle
+ *
+ * The extension that closes {@code @AutoClose} fields implements the
+ * {@link org.junit.jupiter.api.extension.AfterAllCallback AfterAllCallback} and
+ * {@link org.junit.jupiter.api.extension.TestInstancePreDestroyCallback
+ * TestInstancePreDestroyCallback} extension APIs. Consequently, a {@code static}
+ * {@code @AutoClose} field will be closed after all tests in the current test
+ * class have completed, effectively after {@code @AfterAll} methods have executed
+ * for the test class. A non-static {@code @AutoClose} field will be closed before
+ * the current test class instance is destroyed. Specifically, if the test class
+ * is configured with
+ * {@link TestInstance.Lifecycle#PER_METHOD @TestInstance(Lifecycle.PER_METHOD)}
+ * semantics, a non-static {@code @AutoClose} field will be closed after the
+ * execution of each test method, test factory method, or test template method.
+ * However, if the test class is configured with
+ * {@link TestInstance.Lifecycle#PER_CLASS @TestInstance(Lifecycle.PER_CLASS)}
+ * semantics, a non-static {@code @AutoClose} field will not be closed until the
+ * current test class instance is no longer needed, which means after
+ * {@code @AfterAll} methods and after all {@code static} {@code @AutoClose} fields
+ * have been closed.
+ *
+ * @since 5.11
+ */
+@Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@API(status = EXPERIMENTAL, since = "5.11")
+public @interface AutoClose {
+
+ /**
+ * Specify the name of the method to invoke to close the resource.
+ *
+ *
The default value is {@code "close"} which works with any type that
+ * implements {@link AutoCloseable} or has a {@code close()} method.
+ *
+ * @return the name of the method to invoke to close the resource
+ */
+ String value() default "close";
+
+}
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/BeforeAll.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/BeforeAll.java
index 30eba9b73746..197556e7ad3b 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/BeforeAll.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/BeforeAll.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -33,29 +33,27 @@
* be {@code static} by default. Consequently, {@code @BeforeAll} methods are
* not supported in {@link Nested @Nested} test classes or as interface
* default methods unless the test class is annotated with
- * {@link TestInstance @TestInstance(Lifecycle.PER_CLASS)}.
- * However, beginning with Java 16 {@code @BeforeAll} methods may be declared as
- * {@code static} in {@link Nested @Nested} test classes, and the
- * {@code Lifecycle.PER_CLASS} restriction no longer applies. {@code @BeforeAll}
- * methods may optionally declare parameters to be resolved by
+ * {@link TestInstance @TestInstance(Lifecycle.PER_CLASS)}. However, beginning
+ * with Java 16 {@code @BeforeAll} methods may be declared as {@code static} in
+ * {@link Nested @Nested} test classes, in which case the {@code Lifecycle.PER_CLASS}
+ * restriction no longer applies. In addition, {@code @BeforeAll} methods may
+ * optionally declare parameters to be resolved by
* {@link org.junit.jupiter.api.extension.ParameterResolver ParameterResolvers}.
*
- *
Using {@code private} visibility for {@code @BeforeAll} methods is
- * strongly discouraged and will be disallowed in a future release.
+ *
Using {@code private} visibility for {@code @BeforeAll} methods is strongly
+ * discouraged and will be disallowed in a future release.
*
*
Inheritance and Execution Order
*
- * {@code @BeforeAll} methods are inherited from superclasses as long as
- * they are not hidden (default mode with {@code static} modifier),
- * overridden, or superseded (i.e., replaced based on
- * signature only, irrespective of Java's visibility rules). Furthermore,
- * {@code @BeforeAll} methods from superclasses will be executed before
- * {@code @BeforeAll} methods in subclasses.
+ *
{@code @BeforeAll} methods are inherited from superclasses as long as they
+ * are not overridden according to the visibility rules of the Java
+ * language. Furthermore, {@code @BeforeAll} methods from superclasses will be
+ * executed before {@code @BeforeAll} methods in subclasses.
*
- *
Similarly, {@code @BeforeAll} methods declared in an interface are
- * inherited as long as they are not hidden or overridden,
- * and {@code @BeforeAll} methods from an interface will be executed before
- * {@code @BeforeAll} methods in the class that implements the interface.
+ *
Similarly, {@code @BeforeAll} methods declared in an interface are inherited
+ * as long as they are not overridden, and {@code @BeforeAll} methods from an
+ * interface will be executed before {@code @BeforeAll} methods in the class that
+ * implements the interface.
*
*
JUnit Jupiter does not guarantee the execution order of multiple
* {@code @BeforeAll} methods that are declared within a single test class or
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/BeforeEach.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/BeforeEach.java
index 37ca2498c889..7aee562c0ac8 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/BeforeEach.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/BeforeEach.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -29,18 +29,19 @@
*
Method Signatures
*
* {@code @BeforeEach} methods must have a {@code void} return type and must
- * not be {@code static}. Using {@code private} visibility is strongly
- * discouraged and will be disallowed in a future release.
- * They may optionally declare parameters to be resolved by
+ * not be {@code static}. In addition, {@code @BeforeEach} methods may optionally
+ * declare parameters to be resolved by
* {@link org.junit.jupiter.api.extension.ParameterResolver ParameterResolvers}.
*
+ *
Using {@code private} visibility for {@code @BeforeEach} methods is strongly
+ * discouraged and will be disallowed in a future release.
+ *
*
Inheritance and Execution Order
*
* {@code @BeforeEach} methods are inherited from superclasses as long as they
- * are not overridden or superseded (i.e., replaced based on
- * signature only, irrespective of Java's visibility rules). Furthermore,
- * {@code @BeforeEach} methods from superclasses will be executed before
- * {@code @BeforeEach} methods in subclasses.
+ * are not overridden according to the visibility rules of the Java
+ * language. Furthermore, {@code @BeforeEach} methods from superclasses will be
+ * executed before {@code @BeforeEach} methods in subclasses.
*
*
Similarly, {@code @BeforeEach} methods declared as interface default
* methods are inherited as long as they are not overridden, and
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassDescriptor.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassDescriptor.java
index 5773e0b007c5..d6c53bee156c 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassDescriptor.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrderer.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrderer.java
index 2bc852b412a5..e27c05abb926 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrderer.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrderer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -15,7 +15,6 @@
import java.util.Collections;
import java.util.Comparator;
-import java.util.Optional;
import org.apiguardian.api.API;
import org.junit.platform.commons.logging.Logger;
@@ -185,8 +184,8 @@ private static int getOrder(ClassDescriptor descriptor) {
*
Custom Seed
*
* By default, the random seed used for ordering classes is the
- * value returned by {@link System#nanoTime()} during static initialization
- * of this class. In order to support repeatable builds, the value of the
+ * value returned by {@link System#nanoTime()} during static class
+ * initialization. In order to support repeatable builds, the value of the
* default random seed is logged at {@code CONFIG} level. In addition, a
* custom seed (potentially the default seed from the previous test plan
* execution) may be specified via the {@value Random#RANDOM_SEED_PROPERTY_NAME}
@@ -202,15 +201,8 @@ class Random implements ClassOrderer {
private static final Logger logger = LoggerFactory.getLogger(Random.class);
- /**
- * Default seed, which is generated during initialization of this class
- * via {@link System#nanoTime()} for reproducibility of tests.
- */
- private static final long DEFAULT_SEED;
-
static {
- DEFAULT_SEED = System.nanoTime();
- logger.config(() -> "ClassOrderer.Random default seed: " + DEFAULT_SEED);
+ logger.config(() -> "ClassOrderer.Random default seed: " + RandomOrdererUtils.DEFAULT_SEED);
}
/**
@@ -231,7 +223,7 @@ class Random implements ClassOrderer {
*
* @see MethodOrderer.Random
*/
- public static final String RANDOM_SEED_PROPERTY_NAME = MethodOrderer.Random.RANDOM_SEED_PROPERTY_NAME;
+ public static final String RANDOM_SEED_PROPERTY_NAME = RandomOrdererUtils.RANDOM_SEED_PROPERTY_NAME;
public Random() {
}
@@ -243,27 +235,7 @@ public Random() {
@Override
public void orderClasses(ClassOrdererContext context) {
Collections.shuffle(context.getClassDescriptors(),
- new java.util.Random(getCustomSeed(context).orElse(DEFAULT_SEED)));
- }
-
- private Optional getCustomSeed(ClassOrdererContext context) {
- return context.getConfigurationParameter(RANDOM_SEED_PROPERTY_NAME).map(configurationParameter -> {
- Long seed = null;
- try {
- seed = Long.valueOf(configurationParameter);
- logger.config(
- () -> String.format("Using custom seed for configuration parameter [%s] with value [%s].",
- RANDOM_SEED_PROPERTY_NAME, configurationParameter));
- }
- catch (NumberFormatException ex) {
- logger.warn(ex,
- () -> String.format(
- "Failed to convert configuration parameter [%s] with value [%s] to a long. "
- + "Using default seed [%s] as fallback.",
- RANDOM_SEED_PROPERTY_NAME, configurationParameter, DEFAULT_SEED));
- }
- return seed;
- });
+ new java.util.Random(RandomOrdererUtils.getSeed(context::getConfigurationParameter, logger)));
}
}
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrdererContext.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrdererContext.java
index 45f60c12679c..9d9d0325cdb9 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrdererContext.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/ClassOrdererContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Disabled.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Disabled.java
index 9a7717053491..44ec76fca882 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Disabled.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Disabled.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -30,11 +30,17 @@
* When applied at the class level, all test methods within that class
* are automatically disabled as well.
*
- *
When applied at the method level, the presence of this annotation does not
- * prevent the test class from being instantiated. Rather, it prevents the
- * execution of the test method and method-level lifecycle callbacks such as
+ *
This annotation is not {@link java.lang.annotation.Inherited @Inherited}.
+ * Consequently, if you wish to apply the same semantics to a subclass, this
+ * annotation must be redeclared on the subclass.
+ *
+ *
If a test method is disabled via this annotation, that prevents execution
+ * of the test method and method-level lifecycle callbacks such as
* {@code @BeforeEach} methods, {@code @AfterEach} methods, and corresponding
- * extension APIs.
+ * extension APIs. However, that does not prevent the test class from being
+ * instantiated, and it does not prevent the execution of class-level lifecycle
+ * callbacks such as {@code @BeforeAll} methods, {@code @AfterAll} methods, and
+ * corresponding extension APIs.
*
* @since 5.0
* @see #value
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayName.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayName.java
index e99ee34c75fc..abc398327f15 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayName.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGeneration.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGeneration.java
index bb0e1bf9f70a..5345e4d7305e 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGeneration.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGeneration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java
index 22c6ec62551d..f396ce850c7d 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicContainer.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicContainer.java
index dcc48186c5ec..5a37b8e156fd 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicContainer.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicContainer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicNode.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicNode.java
index c1a151779f7f..be569469d852 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicNode.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicTest.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicTest.java
index 935951663d48..b61ccb71a57a 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicTest.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DynamicTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -12,6 +12,7 @@
import static java.util.Spliterator.ORDERED;
import static java.util.Spliterators.spliteratorUnknownSize;
+import static org.apiguardian.api.API.Status.EXPERIMENTAL;
import static org.apiguardian.api.API.Status.MAINTAINED;
import java.net.URI;
@@ -226,6 +227,67 @@ public static Stream stream(Stream extends Named> inputStr
.map(input -> dynamicTest(input.getName(), () -> testExecutor.accept(input.getPayload())));
}
+ /**
+ * Generate a stream of dynamic tests based on the given iterator.
+ *
+ * Use this method when the set of dynamic tests is nondeterministic in
+ * nature or when the input comes from an existing {@link Iterator}. See
+ * {@link #stream(Stream)} as an alternative.
+ *
+ *
The given {@code iterator} is responsible for supplying
+ * {@link Named} input values that provide an {@link Executable} code block.
+ * A {@link DynamicTest} comprised of both parts will be added to the
+ * resulting stream for each dynamically supplied input value.
+ *
+ * @param iterator an {@code Iterator} that supplies named executables;
+ * never {@code null}
+ * @param the type of input supplied by the {@code inputStream}
+ * @return a stream of dynamic tests based on the given iterator; never
+ * {@code null}
+ * @since 5.11
+ * @see #dynamicTest(String, Executable)
+ * @see #stream(Stream)
+ * @see NamedExecutable
+ */
+ @API(status = EXPERIMENTAL, since = "5.11")
+ public static , E extends Executable> Stream stream(
+ Iterator extends T> iterator) {
+ Preconditions.notNull(iterator, "iterator must not be null");
+
+ return stream(StreamSupport.stream(spliteratorUnknownSize(iterator, ORDERED), false));
+ }
+
+ /**
+ * Generate a stream of dynamic tests based on the given input stream.
+ *
+ * Use this method when the set of dynamic tests is nondeterministic in
+ * nature or when the input comes from an existing {@link Stream}. See
+ * {@link #stream(Iterator)} as an alternative.
+ *
+ *
The given {@code inputStream} is responsible for supplying
+ * {@link Named} input values that provide an {@link Executable} code block.
+ * A {@link DynamicTest} comprised of both parts will be added to the
+ * resulting stream for each dynamically supplied input value.
+ *
+ * @param inputStream a {@code Stream} that supplies named executables;
+ * never {@code null}
+ * @param the type of input supplied by the {@code inputStream}
+ * @return a stream of dynamic tests based on the given stream; never
+ * {@code null}
+ * @since 5.11
+ * @see #dynamicTest(String, Executable)
+ * @see #stream(Iterator)
+ * @see NamedExecutable
+ */
+ @API(status = EXPERIMENTAL, since = "5.11")
+ public static , E extends Executable> Stream stream(
+ Stream extends T> inputStream) {
+ Preconditions.notNull(inputStream, "inputStream must not be null");
+
+ return inputStream. //
+ map(input -> dynamicTest(input.getName(), input.getPayload()));
+ }
+
private final Executable executable;
private DynamicTest(String displayName, URI testSourceUri, Executable executable) {
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/IndicativeSentencesGeneration.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/IndicativeSentencesGeneration.java
index 97ab817eb4b3..9a24a7e4e1d6 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/IndicativeSentencesGeneration.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/IndicativeSentencesGeneration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodDescriptor.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodDescriptor.java
index 49f62ab2760b..7fbf3f569b32 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodDescriptor.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodOrderer.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodOrderer.java
index c8269f4a705f..4a71d5944551 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodOrderer.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodOrderer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
@@ -248,11 +248,11 @@ private static int getOrder(MethodDescriptor descriptor) {
* Custom Seed
*
* By default, the random seed used for ordering methods is the
- * value returned by {@link System#nanoTime()} during static initialization
- * of this class. In order to support repeatable builds, the value of the
+ * value returned by {@link System#nanoTime()} during static class
+ * initialization. In order to support repeatable builds, the value of the
* default random seed is logged at {@code CONFIG} level. In addition, a
* custom seed (potentially the default seed from the previous test plan
- * execution) may be specified via the {@value ClassOrderer.Random#RANDOM_SEED_PROPERTY_NAME}
+ * execution) may be specified via the {@value Random#RANDOM_SEED_PROPERTY_NAME}
* configuration parameter which can be supplied via the {@code Launcher}
* API, build tools (e.g., Gradle and Maven), a JVM system property, or the JUnit
* Platform configuration file (i.e., a file named {@code junit-platform.properties}
@@ -265,15 +265,8 @@ class Random implements MethodOrderer {
private static final Logger logger = LoggerFactory.getLogger(Random.class);
- /**
- * Default seed, which is generated during initialization of this class
- * via {@link System#nanoTime()} for reproducibility of tests.
- */
- private static final long DEFAULT_SEED;
-
static {
- DEFAULT_SEED = System.nanoTime();
- logger.config(() -> "MethodOrderer.Random default seed: " + DEFAULT_SEED);
+ logger.config(() -> "MethodOrderer.Random default seed: " + RandomOrdererUtils.DEFAULT_SEED);
}
/**
@@ -294,7 +287,7 @@ class Random implements MethodOrderer {
*
* @see ClassOrderer.Random
*/
- public static final String RANDOM_SEED_PROPERTY_NAME = "junit.jupiter.execution.order.random.seed";
+ public static final String RANDOM_SEED_PROPERTY_NAME = RandomOrdererUtils.RANDOM_SEED_PROPERTY_NAME;
public Random() {
}
@@ -306,28 +299,9 @@ public Random() {
@Override
public void orderMethods(MethodOrdererContext context) {
Collections.shuffle(context.getMethodDescriptors(),
- new java.util.Random(getCustomSeed(context).orElse(DEFAULT_SEED)));
+ new java.util.Random(RandomOrdererUtils.getSeed(context::getConfigurationParameter, logger)));
}
- private Optional getCustomSeed(MethodOrdererContext context) {
- return context.getConfigurationParameter(RANDOM_SEED_PROPERTY_NAME).map(configurationParameter -> {
- Long seed = null;
- try {
- seed = Long.valueOf(configurationParameter);
- logger.config(
- () -> String.format("Using custom seed for configuration parameter [%s] with value [%s].",
- RANDOM_SEED_PROPERTY_NAME, configurationParameter));
- }
- catch (NumberFormatException ex) {
- logger.warn(ex,
- () -> String.format(
- "Failed to convert configuration parameter [%s] with value [%s] to a long. "
- + "Using default seed [%s] as fallback.",
- RANDOM_SEED_PROPERTY_NAME, configurationParameter, DEFAULT_SEED));
- }
- return seed;
- });
- }
}
}
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodOrdererContext.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodOrdererContext.java
index cb585b709416..bab5d3e10ec5 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodOrdererContext.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/MethodOrdererContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Named.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Named.java
index 6dee03e4a1ea..e41b4be29ab3 100644
--- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Named.java
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Named.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2023 the original author or authors.
+ * Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/NamedExecutable.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/NamedExecutable.java
new file mode 100644
index 000000000000..16d5a72d2d18
--- /dev/null
+++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/NamedExecutable.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2015-2024 the original author or authors.
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v2.0 which
+ * accompanies this distribution and is available at
+ *
+ * https://www.eclipse.org/legal/epl-v20.html
+ */
+
+package org.junit.jupiter.api;
+
+import static org.apiguardian.api.API.Status.EXPERIMENTAL;
+
+import java.util.Iterator;
+import java.util.stream.Stream;
+
+import org.apiguardian.api.API;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * {@code NamedExecutable} joins {@code Executable} and {@code Named} in a
+ * one self-typed functional interface.
+ *
+ *