From e5e03aef8e6ea74a346193b1b76b3560fc8efc23 Mon Sep 17 00:00:00 2001 From: Rafael Magalhaes Date: Mon, 20 Apr 2026 13:03:00 +0100 Subject: [PATCH] Add testSourceUri support to TestTemplateInvocationContext via TestSource propagation --- .idea/codeStyles/Project.xml | 101 ------------------ .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/icon.png | Bin 12215 -> 0 bytes .idea/vcs.xml | 20 ---- .../TestTemplateInvocationContext.java | 4 + .../TestTemplateInvocationTestDescriptor.java | 15 +++ .../engine/TestTemplateInvocationTests.java | 68 +++++++++++- 7 files changed, 83 insertions(+), 130 deletions(-) delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/icon.png diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index f1009b0955f8..000000000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c2b23..000000000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/icon.png b/.idea/icon.png deleted file mode 100644 index f95f22bc793527da3e8d78be5472fe3fe6cbf974..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12215 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 CT - - - - - - - - - - - - diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/TestTemplateInvocationContext.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/TestTemplateInvocationContext.java index 2f444d1427a1..42264cf0c931 100644 --- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/TestTemplateInvocationContext.java +++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/TestTemplateInvocationContext.java @@ -14,7 +14,9 @@ import static org.apiguardian.api.API.Status.EXPERIMENTAL; import static org.apiguardian.api.API.Status.STABLE; +import java.net.URI; import java.util.List; +import java.util.Optional; import org.apiguardian.api.API; @@ -81,4 +83,6 @@ default List getAdditionalExtensions() { default void prepareInvocation(ExtensionContext context) { } + default Optional getTestSourceUri() { return Optional.empty(); } + } diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestTemplateInvocationTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestTemplateInvocationTestDescriptor.java index b751e4a1b4b4..2fe706966b8b 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestTemplateInvocationTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestTemplateInvocationTestDescriptor.java @@ -14,7 +14,11 @@ import static java.util.Objects.requireNonNull; import static org.apiguardian.api.API.Status.INTERNAL; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.UriSource; import java.lang.reflect.Method; +import java.net.URI; +import java.util.Optional; import java.util.OptionalInt; import java.util.Set; import java.util.function.UnaryOperator; @@ -48,12 +52,15 @@ public class TestTemplateInvocationTestDescriptor extends TestMethodTestDescript private final int index; + private @Nullable URI testSourceUri; + TestTemplateInvocationTestDescriptor(UniqueId uniqueId, Class testClass, Method templateMethod, TestTemplateInvocationContext invocationContext, int index, JupiterConfiguration configuration) { super(uniqueId, invocationContext.getDisplayName(index), testClass, templateMethod, configuration, interceptorCall); this.invocationContext = invocationContext; this.index = index; + this.testSourceUri = invocationContext.getTestSourceUri().orElse(null); } // --- JupiterTestDescriptor ----------------------------------------------- @@ -97,6 +104,14 @@ public void after(JupiterEngineExecutionContext context) { this.invocationContext = null; } + @Override + public Optional getSource() { + if (this.testSourceUri != null) { + return Optional.of(UriSource.from(this.testSourceUri)); + } + return super.getSource(); + } + private TestTemplateInvocationContext requiredInvocationContext() { return requireNonNull(this.invocationContext); } diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/engine/TestTemplateInvocationTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/engine/TestTemplateInvocationTests.java index bf4ae1ede5a7..6fceb7e11499 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/engine/TestTemplateInvocationTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/engine/TestTemplateInvocationTests.java @@ -34,10 +34,8 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.net.URI; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; import java.util.stream.Stream; @@ -82,6 +80,68 @@ */ class TestTemplateInvocationTests extends AbstractJupiterTestEngineTests { + static class TestTemplateWithUriSource { + + @TestTemplate + @ExtendWith(UriProvider.class) + void template() { + } + + static class UriProvider implements TestTemplateInvocationContextProvider { + + @Override + public boolean supportsTestTemplate(ExtensionContext context) { + return true; + } + + @Override + public Stream provideTestTemplateInvocationContexts( + ExtensionContext context) { + + return Stream.of(new TestTemplateInvocationContext() { + + @Override + public String getDisplayName(int invocationIndex) { + return "[1]"; + } + + @Override + public Optional getTestSourceUri() { + return Optional.of(URI.create("custom://test")); + } + }); + } + } + } + + @Test + void templateUsesCustomUriSourceWhenProvided() { + LauncherDiscoveryRequest request = request().selectors( + selectMethod(TestTemplateWithUriSource.class, "template") + ).build(); + + EngineExecutionResults results = executeTests(request); + + Events events = results.allEvents(); + + events.assertStatistics(stats -> stats.dynamicallyRegistered(1)); + + TestDescriptor descriptor = events.dynamicallyRegistered() + .map(Event::getTestDescriptor) + .findFirst() + .orElseThrow(); + + assertThat(descriptor.getSource()).isPresent(); + assertThat(descriptor.getSource().get()) + .isInstanceOf(org.junit.platform.engine.support.descriptor.UriSource.class); + + var uriSource = (org.junit.platform.engine.support.descriptor.UriSource) descriptor.getSource().get(); + + assertThat(uriSource.getUri()).isEqualTo(URI.create("custom://test")); + } + + + @Test void templateWithSingleRegisteredExtensionIsInvoked() { LauncherDiscoveryRequest request = request().selectors(