Skip to content

Commit

Permalink
initial TCK tests for method invokers (#502)
Browse files Browse the repository at this point in the history
* initial TCK tests for method invokers
* initial TCK tests for invoker lookups
* synchronize CDI TCK audit XML in 'web' from 'impl'
  • Loading branch information
Ladicek authored Feb 16, 2024
1 parent 56b9d96 commit 0bc29f8
Show file tree
Hide file tree
Showing 44 changed files with 4,950 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright 2024, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.cdi.tck.tests.full.invokers;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.spi.Extension;
import jakarta.enterprise.inject.spi.ProcessManagedBean;
import jakarta.enterprise.invoke.Invoker;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.cdi.tck.AbstractTest;
import org.jboss.cdi.tck.cdi.Sections;
import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.test.audit.annotations.SpecAssertion;
import org.jboss.test.audit.annotations.SpecVersion;
import org.testng.annotations.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.jboss.cdi.tck.TestGroups.CDI_FULL;
import static org.testng.Assert.assertEquals;

@SpecVersion(spec = "cdi", version = "4.1")
@Test(groups = CDI_FULL)
public class SimpleInvokerTest extends AbstractTest {
@Deployment
public static WebArchive createTestArchive() {
return new WebArchiveBuilder()
.withTestClass(SimpleInvokerTest.class)
.withClasses(MyService.class)
.withExtension(TestExtension.class)
.build();
}

public static class TestExtension implements Extension {
private Map<String, Invoker<?, ?>> invokers = new HashMap<>();

public void myServiceRegistration(@Observes ProcessManagedBean<MyService> pmb) {
pmb.getAnnotatedBeanClass()
.getMethods()
.stream()
.filter(it -> "hello".equals(it.getJavaMember().getName()))
.forEach(it -> invokers.put(it.getJavaMember().getName(), pmb.createInvoker(it).build()));
}

public <T, R> Invoker<T, R> getInvoker(String name) {
return (Invoker<T, R>) invokers.get(name);
}
}

@Test(dataProvider = ARQUILLIAN_DATA_PROVIDER)
@SpecAssertion(section = Sections.METHOD_INVOKERS_FULL, id = "a")
public void test(MyService service) throws Exception {
Invoker<MyService, String> hello = getCurrentManager().getExtension(TestExtension.class).getInvoker("hello");
assertEquals(hello.invoke(service, new Object[]{1, List.of()}), "foobar1[]");
}

@ApplicationScoped
public static class MyService {
public String hello(int param1, List<String> param2) {
return "foobar" + param1 + param2;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2024, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.cdi.tck.tests.full.invokers.invalid;

import jakarta.annotation.Priority;
import jakarta.decorator.Decorator;
import jakarta.decorator.Delegate;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.spi.DeploymentException;
import jakarta.enterprise.inject.spi.Extension;
import jakarta.enterprise.inject.spi.ProcessManagedBean;
import jakarta.inject.Inject;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.cdi.tck.AbstractTest;
import org.jboss.cdi.tck.cdi.Sections;
import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.test.audit.annotations.SpecAssertion;
import org.jboss.test.audit.annotations.SpecVersion;
import org.testng.annotations.Test;

import static org.jboss.cdi.tck.TestGroups.CDI_FULL;

@SpecVersion(spec = "cdi", version = "4.1")
@Test(groups = CDI_FULL)
public class DecoratorInvokerTest extends AbstractTest {
@Deployment
@ShouldThrowException(DeploymentException.class)
public static WebArchive createTestArchive() {
return new WebArchiveBuilder()
.withTestClass(DecoratorInvokerTest.class)
.withClasses(MyService.class, MyDecorator.class)
.withExtension(TestExtension.class)
.build();
}

public static class TestExtension implements Extension {
public void myDecoratorRegistration(@Observes ProcessManagedBean<MyDecorator> pmb) {
pmb.getAnnotatedBeanClass()
.getMethods()
.stream()
.filter(it -> "hello".equals(it.getJavaMember().getName()))
.forEach(it -> pmb.createInvoker(it).build());
}
}

@Test
@SpecAssertion(section = Sections.BUILDING_INVOKER_FULL, id = "a")
public void trigger() {
}

public interface MyService {
String hello();
}

@Decorator
@Priority(1)
public static class MyDecorator implements MyService {
@Inject
@Delegate
MyService delegate;

@Override
public String hello() {
return "decorated: " + delegate.hello();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2024, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.cdi.tck.tests.invokers;

import jakarta.enterprise.invoke.Invoker;

import java.util.Map;

import static org.testng.Assert.assertNotNull;

public class InvokerHolder {
private final Map<String, Invoker<?, ?>> invokers;

public InvokerHolder(Map<String, Invoker<?, ?>> invokers) {
this.invokers = invokers;
}

public <T, R> Invoker<T, R> get(String id) {
Invoker<T, R> result = (Invoker<T, R>) invokers.get(id);
assertNotNull(result);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2024, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.cdi.tck.tests.invokers;

import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.build.compatible.spi.Parameters;
import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator;
import jakarta.enterprise.invoke.Invoker;

import java.util.HashMap;
import java.util.Map;

public class InvokerHolderCreator implements SyntheticBeanCreator<InvokerHolder> {
@Override
public InvokerHolder create(Instance<Object> lookup, Parameters params) {
String[] names = params.get("names", String[].class);
Invoker<?, ?>[] invokers = params.get("invokers", Invoker[].class);
Map<String, Invoker<?, ?>> map = new HashMap<>();
for (int i = 0; i < names.length; i++) {
map.put(names[i], invokers[i]);
}
return new InvokerHolder(map);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2024, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.cdi.tck.tests.invokers;

import jakarta.enterprise.inject.build.compatible.spi.BeanInfo;
import jakarta.enterprise.inject.build.compatible.spi.InvokerFactory;
import jakarta.enterprise.inject.build.compatible.spi.InvokerInfo;
import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents;
import jakarta.enterprise.invoke.InvokerBuilder;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

public abstract class InvokerHolderExtensionBase {
private final Map<String, InvokerInfo> invokers = new LinkedHashMap<>();

protected final void registerInvokers(BeanInfo bean, InvokerFactory invokers, Set<String> methods) {
registerInvokers(bean, invokers, methods, builder -> {});
}

protected final void registerInvokers(BeanInfo bean, InvokerFactory invokers, Set<String> methods,
Consumer<InvokerBuilder<?>> action) {
bean.declaringClass()
.methods()
.stream()
.filter(it -> methods.contains(it.name()))
.forEach(it -> {
InvokerBuilder<InvokerInfo> builder = invokers.createInvoker(bean, it);
action.accept(builder);
registerInvoker(it.name(), builder.build());
});
}

protected final void registerInvoker(String id, InvokerInfo invoker) {
invokers.put(id, invoker);
}

protected final void synthesizeInvokerHolder(SyntheticComponents syn) {
syn.addBean(InvokerHolder.class)
.type(InvokerHolder.class)
.withParam("names", invokers.keySet().toArray(String[]::new))
.withParam("invokers", invokers.values().toArray(InvokerInfo[]::new))
.createWith(InvokerHolderCreator.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright 2024, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.cdi.tck.tests.invokers;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.build.compatible.spi.BeanInfo;
import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension;
import jakarta.enterprise.inject.build.compatible.spi.InvokerFactory;
import jakarta.enterprise.inject.build.compatible.spi.Registration;
import jakarta.enterprise.inject.build.compatible.spi.Synthesis;
import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents;
import jakarta.enterprise.invoke.Invoker;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.cdi.tck.AbstractTest;
import org.jboss.cdi.tck.cdi.Sections;
import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.test.audit.annotations.SpecAssertion;
import org.jboss.test.audit.annotations.SpecVersion;
import org.testng.annotations.Test;

import java.util.List;
import java.util.Set;

import static org.testng.Assert.assertEquals;

@SpecVersion(spec = "cdi", version = "4.1")
public class SimpleInvokerTest extends AbstractTest {
@Deployment
public static WebArchive createTestArchive() {
return new WebArchiveBuilder()
.withTestClass(SimpleInvokerTest.class)
.withClasses(MyService.class)
.withBuildCompatibleExtension(TestExtension.class)
.withClasses(InvokerHolder.class, InvokerHolderCreator.class, InvokerHolderExtensionBase.class)
.build();
}

public static class TestExtension extends InvokerHolderExtensionBase implements BuildCompatibleExtension {
@Registration(types = MyService.class)
public void myServiceRegistration(BeanInfo bean, InvokerFactory invokers) {
registerInvokers(bean, invokers, Set.of("hello"));
}

@Synthesis
public void synthesis(SyntheticComponents syn) {
synthesizeInvokerHolder(syn);
}
}

@Test(dataProvider = ARQUILLIAN_DATA_PROVIDER)
@SpecAssertion(section = Sections.METHOD_INVOKERS, id = "a")
@SpecAssertion(section = Sections.BUILDING_INVOKER, id = "a")
@SpecAssertion(section = Sections.BUILDING_INVOKER, id = "e")
@SpecAssertion(section = Sections.USING_INVOKER_BUILDER, id = "a")
public void test(MyService service, InvokerHolder invokers) throws Exception {
Invoker<MyService, String> hello = invokers.get("hello");
assertEquals(hello.invoke(service, new Object[]{1, List.of()}), "foobar1[]");
}

@ApplicationScoped
public static class MyService {
public String hello(int param1, List<String> param2) {
return "foobar" + param1 + param2;
}
}
}
Loading

0 comments on commit 0bc29f8

Please sign in to comment.