Hi, Wouldn't it be nice, if CDI would also resolve method parameters? See patch.
Regards, Philipp
diff --git a/webbeans-junit5/pom.xml b/webbeans-junit5/pom.xml index 23f18161b..0e0807621 100644 --- a/webbeans-junit5/pom.xml +++ b/webbeans-junit5/pom.xml @@ -76,17 +76,9 @@ <execution> <id>default-test</id> <configuration> - <skip>true</skip> - </configuration> - </execution> - <execution> - <id>perclass</id> - <phase>test</phase> - <goals> - <goal>test</goal> - </goals> - <configuration> - <includes>**/perclass/*</includes> + <excludes> + <exclude>**/reusable/*</exclude> + </excludes> </configuration> </execution> <execution> @@ -96,7 +88,9 @@ <goal>test</goal> </goals> <configuration> - <includes>**/reusable/*</includes> + <includes> + <include>**/reusable/*</include> + </includes> </configuration> </execution> </executions> diff --git a/webbeans-junit5/src/main/java/org/apache/openwebbeans/junit5/internal/CdiExtension.java b/webbeans-junit5/src/main/java/org/apache/openwebbeans/junit5/internal/CdiExtension.java index 382b90c7a..94e5ed52a 100644 --- a/webbeans-junit5/src/main/java/org/apache/openwebbeans/junit5/internal/CdiExtension.java +++ b/webbeans-junit5/src/main/java/org/apache/openwebbeans/junit5/internal/CdiExtension.java @@ -24,6 +24,9 @@ import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; import org.junit.platform.commons.util.AnnotationUtils; import javax.enterprise.context.spi.CreationalContext; @@ -34,19 +37,22 @@ import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.InjectionTarget; import java.io.Closeable; import java.io.IOException; +import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Parameter; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Objects; import java.util.function.Supplier; import java.util.stream.Stream; // todo: enhance the setup to be thread safe? see Meecrowave ClassLoaderLock class and friends -public class CdiExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback +public class CdiExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver { private static SeContainer reusableContainer; - private SeContainer container; + private SeContainer testInstanceContainer; private Collection<CreationalContext<Object>> creationalContexts = new ArrayList<>(); private Closeable[] onStop; @@ -104,32 +110,34 @@ public class CdiExtension implements BeforeAllCallback, AfterAllCallback, Before .peek(Supplier::get) .filter(Objects::nonNull) .toArray(Closeable[]::new); + SeContainer container = initializer.initialize(); if (reusable) { - reusableContainer = initializer.initialize(); + reusableContainer = container; Runtime.getRuntime().addShutdownHook(new Thread( () -> doClose(reusableContainer), getClass().getName() + "-shutdown")); } else { - container = initializer.initialize(); + testInstanceContainer = container; } } @Override public void afterAll(final ExtensionContext extensionContext) { - if (container != null) + if (testInstanceContainer != null) { - doClose(container); - container = null; + doClose(testInstanceContainer); + testInstanceContainer = null; } } @Override public void beforeEach(final ExtensionContext extensionContext) { - if (container == null && reusableContainer == null) + SeContainer container = getContainer(); + if (container == null) { return; } @@ -137,7 +145,7 @@ public class CdiExtension implements BeforeAllCallback, AfterAllCallback, Before { testInstances.getAllInstances().stream().distinct().forEach(instance -> { - final BeanManager manager = (container == null ? reusableContainer : container).getBeanManager(); + final BeanManager manager = container.getBeanManager(); final AnnotatedType<?> annotatedType = manager.createAnnotatedType(instance.getClass()); final InjectionTarget injectionTarget = manager.createInjectionTarget(annotatedType); final CreationalContext<Object> creationalContext = manager.createCreationalContext(null); @@ -172,4 +180,43 @@ public class CdiExtension implements BeforeAllCallback, AfterAllCallback, Before } }); } + + private SeContainer getContainer() + { + return (testInstanceContainer == null ? reusableContainer : testInstanceContainer); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) + throws ParameterResolutionException + { + SeContainer container = getContainer(); + if (container == null) + { + return false; + } + return container.select( + parameterContext.getParameter().getType(), + getQualifiers(parameterContext.getParameter()) + ).isResolvable(); + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) + throws ParameterResolutionException + { + return getContainer().select( + parameterContext.getParameter().getType(), + getQualifiers(parameterContext.getParameter()) + ).get(); + } + + private Annotation[] getQualifiers(Parameter parameter) + { + SeContainer container = getContainer(); + return Arrays.stream(parameter.getAnnotations()) + .filter(annotation -> container.getBeanManager().isQualifier(annotation.annotationType())) + .toArray(Annotation[]::new); + } + } diff --git a/webbeans-junit5/src/test/java/org/apache/openwebbeans/junit5/parameter/ParameterResolutionTest.java b/webbeans-junit5/src/test/java/org/apache/openwebbeans/junit5/parameter/ParameterResolutionTest.java new file mode 100644 index 000000000..6c5bd7913 --- /dev/null +++ b/webbeans-junit5/src/test/java/org/apache/openwebbeans/junit5/parameter/ParameterResolutionTest.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openwebbeans.junit5.parameter; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.apache.openwebbeans.junit5.Cdi; +import org.apache.openwebbeans.junit5.bean.MyService; +import org.junit.jupiter.api.Test; + +@Cdi(disableDiscovery = true, classes = MyService.class) +class ParameterResolutionTest +{ + @Test + void test1(MyService service) + { + assertEquals("ok", service.ok()); + } +}