Skip to content

Commit

Permalink
Merge branch 'main' into add-resource-container-selector-resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
mpkorstanje authored Sep 26, 2024
2 parents f0f1100 + d013085 commit 0627ca3
Show file tree
Hide file tree
Showing 32 changed files with 365 additions and 121 deletions.
2 changes: 1 addition & 1 deletion .github/actions/run-gradle/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ inputs:
runs:
using: "composite"
steps:
- uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4
- uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4
id: setup-gradle-jdk
with:
distribution: temurin
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup-test-jdk/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ inputs:
runs:
using: "composite"
steps:
- uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4
- uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4
with:
distribution: ${{ inputs.distribution }}
java-version: 8
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ jobs:
- name: Check out repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- name: Initialize CodeQL
uses: github/codeql-action/init@294a9d92911152fe08befb9ec03e240add280cb3 # v3
uses: github/codeql-action/init@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3
with:
languages: ${{ matrix.language }}
tools: latest
tools: linked
- name: Build
uses: ./.github/actions/run-gradle
with:
Expand All @@ -44,4 +44,4 @@ jobs:
-Dscan.tag.CodeQL \
allMainClasses
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@294a9d92911152fe08befb9ec03e240add280cb3 # v3
uses: github/codeql-action/analyze@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3
4 changes: 2 additions & 2 deletions .github/workflows/cross-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
version: latest
- name: "Set up JDK ${{ matrix.jdk.version }} (${{ matrix.jdk.distribution || 'temurin' }})"
if: matrix.jdk.type == 'ga'
uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4
with:
distribution: ${{ matrix.jdk.distribution || 'temurin' }}
java-version: ${{ matrix.jdk.version }}
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
with:
distribution: semeru
- name: 'Set up JDK ${{ matrix.jdk }}'
uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4
with:
distribution: semeru
java-version: ${{ matrix.jdk }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gradle-dependency-submission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
with:
fetch-depth: 1
- name: Setup Java
uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4
with:
distribution: temurin
java-version: 21
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This repository is the home of _JUnit 5_.

## Latest Releases

- General Availability (GA): [JUnit 5.11.0](https://github.com/junit-team/junit5/releases/tag/r5.11.0) (August 14, 2024)
- General Availability (GA): [JUnit 5.11.1](https://github.com/junit-team/junit5/releases/tag/r5.11.1) (September 25, 2024)
- Preview (Milestone/Release Candidate): N/A

## Documentation
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[[release-notes-5.11.1]]
== 5.11.1

*Date of Release:*
*Date of Release:* September 25, 2024

*Scope:* minor bug fixes and improvements since 5.11.0
*Scope:* Bug fixes and enhancements since 5.11.0

For a complete list of all _closed_ issues and pull requests for this release, consult the
link:{junit5-repo}+/milestone/79?closed=1+[5.11.1] milestone page in the JUnit repository
link:{junit5-repo}+/milestone/80?closed=1+[5.11.1] milestone page in the JUnit repository
on GitHub.


Expand All @@ -16,17 +16,14 @@ on GitHub.
[[release-notes-5.11.1-junit-platform-bug-fixes]]
==== Bug Fixes

* Fixed potential locking issue with `ExclusiveResource` in the
`HierarchicalTestExecutorService`, which could lead to deadlocks in certain scenarios.
* Fix support for disabling ANSI colors on the console when the `NO_COLOR` environment
variable is available.
* `NamespacedHierarchicalStore` no longer throws an exception after it has been closed if
the store is queried via one of the `get(...)` or `getOrComputeIfAbsent(...)` methods;
however, if a `getOrComputeIfAbsent(...)` invocation results in the computation of a new
value, an exception will still be thrown.

[[release-notes-5.11.1-junit-platform-deprecations-and-breaking-changes]]
==== Deprecations and Breaking Changes

* ❓
* Fixed potential locking issue with `ExclusiveResource` in the
`HierarchicalTestExecutorService`, which could lead to deadlocks in certain scenarios.

[[release-notes-5.11.1-junit-platform-new-features-and-improvements]]
==== New Features and Improvements
Expand All @@ -45,11 +42,6 @@ on GitHub.
* `TestWatcher` callback methods can once again access data in the
`ExtensionContext.Store`.

[[release-notes-5.11.1-junit-jupiter-deprecations-and-breaking-changes]]
==== Deprecations and Breaking Changes

* ❓

[[release-notes-5.11.1-junit-jupiter-new-features-and-improvements]]
==== New Features and Improvements

Expand All @@ -60,17 +52,4 @@ on GitHub.
[[release-notes-5.11.1-junit-vintage]]
=== JUnit Vintage

[[release-notes-5.11.1-junit-vintage-bug-fixes]]
==== Bug Fixes

* ❓

[[release-notes-5.11.1-junit-vintage-deprecations-and-breaking-changes]]
==== Deprecations and Breaking Changes

* ❓

[[release-notes-5.11.1-junit-vintage-new-features-and-improvements]]
==== New Features and Improvements

* ❓
No changes.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ support the discovery of class path resource based tests, analogous to the
[[release-notes-5.12.0-M1-junit-jupiter-new-features-and-improvements]]
==== New Features and Improvements

* ❓
* In a `@ParameterizedTest` method, a `null` value can now be supplied for Java Date/Time
types such as `LocalDate` if the new `nullable` attribute in
`@JavaTimeConversionPattern` is set to `true`.
* `ArgumentsProvider` (declared via `@ArgumentsSource`), `ArgumentConverter` (declared via
`@ConvertWith`), and `ArgumentsAggregator` (declared via `@AggregateWith`)
implementations can now use constructor injection from registered `ParameterResolver`
extensions.


[[release-notes-5.12.0-M1-junit-vintage]]
Expand Down
9 changes: 9 additions & 0 deletions documentation/src/docs/asciidoc/user-guide/writing-tests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,15 @@ If you wish to implement a custom `ArgumentsProvider` that also consumes an anno
(like built-in providers such as `{ValueArgumentsProvider}` or `{CsvArgumentsProvider}`),
you have the possibility to extend the `{AnnotationBasedArgumentsProvider}` class.

Moreover, `ArgumentsProvider` implementations may declare constructor parameters in case
they need to be resolved by a registered `ParameterResolver` as demonstrated in the
following example.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ArgumentsProviderWithConstructorInjection_example]
----

[[writing-tests-parameterized-repeatable-sources]]
===== Multiple sources using repeatable annotations
Repeatable annotations provide a convenient way to specify multiple sources from
Expand Down
23 changes: 23 additions & 0 deletions documentation/src/test/java/example/ParameterizedTestDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,29 @@ public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
}
// end::ArgumentsProvider_example[]

@ParameterizedTest
@ArgumentsSource(MyArgumentsProviderWithConstructorInjection.class)
void testWithArgumentsSourceWithConstructorInjection(String argument) {
assertNotNull(argument);
}

static
// tag::ArgumentsProviderWithConstructorInjection_example[]
public class MyArgumentsProviderWithConstructorInjection implements ArgumentsProvider {

private final TestInfo testInfo;

public MyArgumentsProviderWithConstructorInjection(TestInfo testInfo) {
this.testInfo = testInfo;
}

@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return Stream.of(Arguments.of(testInfo.getDisplayName()));
}
}
// end::ArgumentsProviderWithConstructorInjection_example[]

// tag::ParameterResolver_example[]
@BeforeEach
void beforeEach(TestInfo testInfo) {
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "lo
log4j-jul = { module = "org.apache.logging.log4j:log4j-jul", version.ref = "log4j" }
maven = { module = "org.apache.maven:apache-maven", version = "3.9.9" }
mavenSurefirePlugin = { module = "org.apache.maven.plugins:maven-surefire-plugin", version.ref = "surefire" }
memoryfilesystem = { module = "com.github.marschall:memoryfilesystem", version = "2.8.0" }
memoryfilesystem = { module = "com.github.marschall:memoryfilesystem", version = "2.8.1" }
mockito = { module = "org.mockito:mockito-junit-jupiter", version = "5.13.0" }
nohttp-checkstyle = { module = "io.spring.nohttp:nohttp-checkstyle", version = "0.0.11" }
opentest4j = { module = "org.opentest4j:opentest4j", version.ref = "opentest4j" }
Expand All @@ -61,7 +61,7 @@ openTestReporting-tooling = { module = "org.opentest4j.reporting:open-test-repor
picocli = { module = "info.picocli:picocli", version = "4.7.6" }
slf4j-julBinding = { module = "org.slf4j:slf4j-jdk14", version = "2.0.16" }
spock1 = { module = "org.spockframework:spock-core", version = "1.3-groovy-2.5" }
univocity-parsers = { module = "com.univocity:univocity-parsers", version = "2.9.1" }
univocity-parsers = { module = "com.sonofab1rd:univocity-parsers", version = "2.10.1" }
xmlunit-assertj = { module = "org.xmlunit:xmlunit-assertj3", version.ref = "xmlunit" }
xmlunit-placeholders = { module = "org.xmlunit:xmlunit-placeholders", version.ref = "xmlunit" }
testingAnnotations = { module = "com.gradle:develocity-testing-annotations", version = "2.0.1" }
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

import org.apiguardian.api.API;
import org.junit.jupiter.api.extension.ExtensionContext;
Expand Down Expand Up @@ -100,18 +101,22 @@ public JupiterEngineExecutionContext execute(JupiterEngineExecutionContext conte
List<TestTemplateInvocationContextProvider> providers = validateProviders(extensionContext,
context.getExtensionRegistry());
AtomicInteger invocationIndex = new AtomicInteger();
// @formatter:off
providers.stream()
.flatMap(provider -> provider.provideTestTemplateInvocationContexts(extensionContext))
.map(invocationContext -> createInvocationTestDescriptor(invocationContext, invocationIndex.incrementAndGet()))
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(invocationTestDescriptor -> execute(dynamicTestExecutor, invocationTestDescriptor));
// @formatter:on
for (TestTemplateInvocationContextProvider provider : providers) {
try (Stream<TestTemplateInvocationContext> stream = invocationContexts(provider, extensionContext)) {
stream.forEach(
invocationContext -> toTestDescriptor(invocationContext, invocationIndex.incrementAndGet()) //
.ifPresent(testDescriptor -> execute(dynamicTestExecutor, testDescriptor)));
}
}
validateWasAtLeastInvokedOnce(invocationIndex.get(), providers);
return context;
}

private static Stream<TestTemplateInvocationContext> invocationContexts(
TestTemplateInvocationContextProvider provider, ExtensionContext extensionContext) {
return provider.provideTestTemplateInvocationContexts(extensionContext);
}

private List<TestTemplateInvocationContextProvider> validateProviders(ExtensionContext extensionContext,
ExtensionRegistry extensionRegistry) {

Expand All @@ -126,8 +131,7 @@ private List<TestTemplateInvocationContextProvider> validateProviders(ExtensionC
TestTemplateInvocationContextProvider.class.getSimpleName(), getTestMethod()));
}

private Optional<TestDescriptor> createInvocationTestDescriptor(TestTemplateInvocationContext invocationContext,
int index) {
private Optional<TestDescriptor> toTestDescriptor(TestTemplateInvocationContext invocationContext, int index) {
UniqueId uniqueId = getUniqueId().append(TestTemplateInvocationTestDescriptor.SEGMENT_TYPE, "#" + index);
if (getDynamicDescendantFilter().test(uniqueId, index - 1)) {
return Optional.of(new TestTemplateInvocationTestDescriptor(uniqueId, getTestClass(), getTestMethod(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public void formatTestNames(Blackhole blackhole) throws Exception {
var formatter = new ParameterizedTestNameFormatter(
ParameterizedTest.DISPLAY_NAME_PLACEHOLDER + " " + ParameterizedTest.DEFAULT_DISPLAY_NAME + " ({0})",
"displayName",
new ParameterizedTestMethodContext(TestCase.class.getDeclaredMethod("parameterizedTest", int.class)), 512);
new ParameterizedTestMethodContext(TestCase.class.getDeclaredMethod("parameterizedTest", int.class), null),
512);
for (int i = 0; i < argumentsList.size(); i++) {
Arguments arguments = argumentsList.get(i);
blackhole.consume(formatter.format(i, arguments, arguments.get()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.support.AnnotationConsumerInitializer;
import org.junit.platform.commons.JUnitException;
import org.junit.platform.commons.support.ReflectionSupport;
import org.junit.platform.commons.util.ExceptionUtils;
import org.junit.platform.commons.util.Preconditions;

Expand All @@ -52,7 +50,7 @@ public boolean supportsTestTemplate(ExtensionContext context) {
return false;
}

ParameterizedTestMethodContext methodContext = new ParameterizedTestMethodContext(testMethod);
ParameterizedTestMethodContext methodContext = new ParameterizedTestMethodContext(testMethod, context);

Preconditions.condition(methodContext.hasPotentiallyValidSignature(),
() -> String.format(
Expand Down Expand Up @@ -84,7 +82,7 @@ public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContex
return findRepeatableAnnotations(templateMethod, ArgumentsSource.class)
.stream()
.map(ArgumentsSource::value)
.map(this::instantiateArgumentsProvider)
.map(clazz -> ParameterizedTestSpiInstantiator.instantiate(ArgumentsProvider.class, clazz, extensionContext))
.map(provider -> AnnotationConsumerInitializer.initialize(templateMethod, provider))
.flatMap(provider -> arguments(provider, extensionContext))
.map(arguments -> {
Expand All @@ -97,23 +95,6 @@ public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContex
// @formatter:on
}

@SuppressWarnings("ConstantConditions")
private ArgumentsProvider instantiateArgumentsProvider(Class<? extends ArgumentsProvider> clazz) {
try {
return ReflectionSupport.newInstance(clazz);
}
catch (Exception ex) {
if (ex instanceof NoSuchMethodException) {
String message = String.format("Failed to find a no-argument constructor for ArgumentsProvider [%s]. "
+ "Please ensure that a no-argument constructor exists and "
+ "that the class is either a top-level class or a static nested class",
clazz.getName());
throw new JUnitException(message, ex);
}
throw ex;
}
}

private ExtensionContext.Store getStore(ExtensionContext context) {
return context.getStore(Namespace.create(ParameterizedTestExtension.class, context.getRequiredTestMethod()));
}
Expand Down
Loading

0 comments on commit 0627ca3

Please sign in to comment.